一、pom.xml

<dependency><groupId>com.esotericsoftware</groupId><artifactId>kryo</artifactId><version>4.0.0</version>
</dependency>

二、封装工具类

package com.cxs.web.system.kryo;import com.cxs.common.util.ArrayUtil;
import com.cxs.common.util.Collections;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.pool.KryoCallback;
import com.esotericsoftware.kryo.pool.KryoFactory;
import com.esotericsoftware.kryo.pool.KryoPool;
import org.objenesis.strategy.StdInstantiatorStrategy;
import org.springframework.util.StopWatch;import java.io.*;
import java.util.*;/*** KryoUtils序列化和反序列化操作官方文档:中文:https://blog.csdn.net/fanjunjaden/article/details/72823866英文:https://github.com/EsotericSoftware/kryo*/
public class KryoUtils  {/* Kryo有三组读写对象的方法* 1.如果不知道对象的具体类,且对象可以为null: kryo.writeClassAndObject(output, object); Object object = kryo.readClassAndObject(input);* 2.如果类已知且对象可以为null: kryo.writeObjectOrNull(output, someObject); SomeClass someObject = kryo.readObjectOrNull(input, SomeClass.class);* 3.如果类已知且对象不能为null:  kryo.writeObject(output, someObject); SomeClass someObject = kryo.readObject(input, SomeClass.class);*//*** (池化Kryo实例)使用ThreadLocal*/private static final ThreadLocal<Kryo> KRYOS = new ThreadLocal<Kryo>() {@Overrideprotected Kryo initialValue() {Kryo kryo = new Kryo();/*** 不要轻易改变这里的配置,更改之后,序列化的格式就会发生变化,* 上线的同时就必须清除 Redis 里的所有缓存,* 否则那些缓存再回来反序列化的时候,就会报错*///支持对象循环引用(否则会栈溢出)kryo.setReferences(true); //默认值就是 true,添加此行的目的是为了提醒维护者,不要改变这个配置//不强制要求注册类(注册行为无法保证多个 JVM 内同一个类的注册编号相同;而且业务系统中大量的 Class 也难以一一注册)kryo.setRegistrationRequired(false); //默认值就是 false,添加此行的目的是为了提醒维护者,不要改变这个配置//Fix the NPE bug when deserializing Collections.((Kryo.DefaultInstantiatorStrategy) kryo.getInstantiatorStrategy()).setFallbackInstantiatorStrategy(new StdInstantiatorStrategy());return kryo;}};/*** (池化Kryo实例)使用KryoPool*//*private static KryoFactory factory1 = new KryoFactory() {@Overridepublic Kryo create () {return new Kryo();}};private static KryoFactory  factory2 = () -> { return new Kryo(); };private static KryoFactory  factory3 = () -> new Kryo();*/private static KryoFactory  factory = Kryo::new;private static KryoPool pool = new KryoPool.Builder(factory).softReferences().build();/*** 使用ThreadLocal创建Kryo* 把java对象序列化成byte[];* @param obj java对象* @return*/public static <T>  byte[] serializeObject(T obj) {ByteArrayOutputStream os=null;Output output=null;if(null != obj){Kryo kryo = KRYOS.get();try {os = new ByteArrayOutputStream();output = new Output(os);kryo.writeObject(output, obj);close(output);return os.toByteArray();} catch (Exception e) {e.printStackTrace();}finally {close(os);}}return null;}/*** 使用ThreadLocal创建Kryo* 把byte[]反序列化成指定的java对象* @param bytes* @param t 指定的java对象* @param <T>* @return 指定的java对象*/public static <T> T unSerializeObject(byte[] bytes,Class<T> t) {ByteArrayInputStream is=null;Input input=null;if(null != bytes && bytes.length>0 && null!=t){try {Kryo kryo = KRYOS.get();is = new ByteArrayInputStream(bytes);input = new Input(is);return kryo.readObject(input,t);} catch (Exception e) {e.printStackTrace();}finally {close(is);close(input);}}return null;}/*** 使用ThreadLocal创建Kryo* 把List序列化成byte[];* @param list java对象* @return*/public static <T>  byte[]  serializeList(List<T> list ) {ByteArrayOutputStream os=null;Output output=null;byte[] bytes = null;if(null != list && list.size()>0){Kryo kryo = KRYOS.get();try {os = new ByteArrayOutputStream();output = new Output(os);kryo.writeObject(output,list);close(output);bytes = os.toByteArray();return bytes;} catch (Exception e) {e.printStackTrace();}finally {close(os);}}return null;}/*** 使用ThreadLocal创建Kryo* 把byte[]反序列化成指定的List<T>* @param bytes byte数组* @param <T>* @return 指定java对象的List*/public static <T> List<T> unSerializeList(byte[] bytes) {ByteArrayInputStream is=null;Input input=null;if(null !=bytes && bytes.length>0){try {Kryo kryo = KRYOS.get();is = new ByteArrayInputStream(bytes);input = new Input(is);List<T> list = kryo.readObject(input,ArrayList.class);return list;} catch (Exception e) {e.printStackTrace();}finally {close(is);close(input);}}return null;}/*** 使用ThreadLocal创建Kryo* 把java对象转序列化存储在文件中;* @param obj java对象* @return*/public static <T>  boolean serializeFile(T obj,String path) {if(null != obj){Output output=null;try {Kryo kryo = KRYOS.get();output = new Output(new FileOutputStream(path));kryo.writeObject(output, obj);return true;} catch (Exception e) {e.printStackTrace();}finally {close(output);}}return false;}/*** 使用ThreadLocal创建Kryo* 把序列化的文件反序列化成指定的java对象* @param path 文件路径* @param t 指定的java对象* @param <T>* @return 指定的java对象*/public static <T> T unSerializeFile(String path,Class<T> t) {if(null != path && null !=t ){Input input=null;try {Kryo kryo = KRYOS.get();input = new Input(new FileInputStream(path));return kryo.readObject(input,t);} catch (Exception e) {e.printStackTrace();}finally {close(input);}}return null;}/*** 使用KryoPool SoftReferences创建Kryo* 把java对象序列化成byte[] ;* @param obj java对象* @return*/public static <T>  byte[] serializePoolSoftReferences (T obj) {if(null!=obj){Kryo kryo =pool.borrow();ByteArrayOutputStream os=null;Output output=null;try {os = new ByteArrayOutputStream();output = new Output(os);kryo.writeObject(output, obj);close(output);byte [] bytes = os.toByteArray();return bytes;} catch (Exception e) {e.printStackTrace();}finally {pool.release(kryo);close(os);}}return null;}/*** 使用KryoPool SoftReferences创建Kryo* 把byte[]反序列化成指定的java对象* @param bytes* @return*/public static <T> T unSerializePoolSoftReferences(byte[] bytes,Class<T> t) {if(null !=bytes && bytes.length>0 && null!=t){Kryo kryo =pool.borrow();ByteArrayInputStream is=null;Output output=null;try {is = new ByteArrayInputStream(bytes);Input input= new Input(is);return kryo.readObject(input, t);} catch (Exception e) {e.printStackTrace();}finally {pool.release(kryo);close(is);close(output);}}return null;}/*** 使用KryoPool SoftReferences创建Kryo* 把java对象序列化成byte[] ;* @param obj java对象* @return*/public static <T>  byte[] serializePoolCallback (final T obj) {if(null != obj){try {return pool.run(new KryoCallback<byte[]>() {@Overridepublic byte[] execute(Kryo kryo) {ByteArrayOutputStream os = new ByteArrayOutputStream();Output output = new Output(os);kryo.writeObject(output,obj);output.close();try {os.close();} catch (IOException e) {e.printStackTrace();}return os.toByteArray();}});} catch (Exception e) {e.printStackTrace();}}return null;}/*** 使用KryoPool SoftReferences创建Kryo* 把byte[]反序列化成指定的java对象* @param bytes* @return*/public static <T> T unSerializePoolCallback(final byte[] bytes, final Class<T> t) {if(null != bytes && bytes.length>0 && null != t){try {return pool.run(new KryoCallback<T>() {@Overridepublic T execute(Kryo kryo) {ByteArrayInputStream is = new ByteArrayInputStream(bytes);Input input = new Input(is);T result =kryo.readObject(input,t);input.close();try {is.close();} catch (IOException e) {e.printStackTrace();}return result;}});} catch (Exception e) {e.printStackTrace();}}return null;}/*** 关闭io流对象** @param closeable*/public static void close(Closeable closeable) {if (closeable != null) {try {closeable.close();} catch (Exception e) {e.printStackTrace();}}}public static void main(String[] args) throws FileNotFoundException {Clazz clazz1 = new Clazz("3年级1班", "java", 1);Clazz clazz2 = new Clazz("3年级2班", ".net", 2);Clazz clazz3 = new Clazz("3年级3班", "vue", 3);Student student1 = new Student("张三", 18, new Date(), '1', true, clazz1);Student student2 = new Student("李四", 28, new Date(System.currentTimeMillis()-1000*60*60*24), '1', true, clazz1);Student student3 = new Student("王五", 38, new Date(System.currentTimeMillis()-1000*60*60*24*2), '2', false, clazz2);Student student4 = new Student("赵六", 48, new Date(System.currentTimeMillis()-1000*60*60*24*3), '1', true, clazz3);Student student5 = new Student("刘七", 58, new Date(System.currentTimeMillis()-1000*60*60*24*4), '2', false, clazz1);List<Student> studentList = Arrays.asList(student1, student2, student3, student4, student5);System.out.println("===kryo序列化===");StopWatch stopWatch = new StopWatch("kryo序列化/反序列化");stopWatch.start("kryo序列化/反序列化");for(int i = 0; i < 1000000; i++) {unSerializeObject(serializeObject(studentList), ArrayList.class);}stopWatch.stop();System.out.println(stopWatch.getId() + "-totalTimeMillis:" + stopWatch.getTotalTimeMillis());System.out.println("===jdk序列化===");stopWatch = new StopWatch("jdk序列化/反序列化");stopWatch.start("jdk序列化/反序列化");for(int i = 0; i < 1000000; i++) {Collections.deepCopy(studentList);}stopWatch.stop();System.out.println(stopWatch.getId() + "-totalTimeMillis:" + stopWatch.getTotalTimeMillis());}
}

三、与jdk序列化/反序列化的性能测试

1. 循环1万次测试


测试结果:kryo高于jdk 3倍效率

2. 循环10万次测试


测试结果:kryo高于jdk 4倍效率

3. 循环100万次测试

测试结果:kryo高于jdk 5倍效率

四、总结

序列化/反序列化 次数越多,效果越明显!

Kryo 高性能序列化和反序列化相关推荐

  1. 高性能的序列化与反序列化:kryo的简单使用

    前言:kryo是个高效的java序列化/反序列化库,目前Twitter.yahoo.Apache.strom等等在使用该技术,比如Apache的spark.hive等大数据领域用的较多. 为什么使用k ...

  2. 【RPC】序列化与反序列化

    文章目录 1. 基本概念? 2. 文本格式的序列化方案 2.1 XML格式 2.2 JSON格式 3. 二进制格式的序列化方法 4. 序列化框架选型 1. 基本概念? 序列化和反序列化是一种数据转化的 ...

  3. Java序列化与反序列化的深度思考

    目录 1.序列化与反序列化的作用 2.序列化协议 2.1 JDK序列化协议 2.1.1  Externalizable与Serializable的异同 2.2 Google ProtocolBuf 协 ...

  4. dubbo源码分析25 -- 序列化与反序列化

    序列化:把对象转换为字节序列的过程称为对象的序列化. 反序列化:把字节序列恢复为对象的过程称为对象的反序列化. Dubbo是 Alibaba 开源的分布式服务框架远程调用框架,现在已捐赠给 apach ...

  5. 序列化和反序列化(转)

    转载:http://kb.cnblogs.com/page/515982/ 摘要 序列化和反序列化几乎是工程师们每天都要面对的事情,但是要精确掌握这两个概念并不容易:一方面,它们往往作为框架的一部分出 ...

  6. 使用Kryo的序列化方式提升Netty性能

    2019独角兽企业重金招聘Python工程师标准>>> 为什么选择Kryo? 首先,Kryo的序列化方式,在性能方面是比较好的,和Protobuf差不多,比Java原生的序列化方式快 ...

  7. Redkale 技术详解 03 -- Convert高性能序列化

    2019独角兽企业重金招聘Python工程师标准>>> Convert是个重复造轮子的组件,却是个飞速的轮子.Redkale之所以重复造轮子主要追求性能和需要与网络数据的序列化很好的 ...

  8. 序列化和反序列化--转

    http://www.infoq.com/cn/articles/serialization-and-deserialization 简介 文章作者服务于美团推荐与个性化组,该组致力于为美团用户提供每 ...

  9. java高性能序列化_Java最佳实践–高性能序列化

    java高性能序列化 在使用Java编程语言时,我们将继续讨论与建议的实践有关的系列文章,我们将讨论并演示如何将对象序列化用于高性能应用程序. 所有讨论的主题均基于用例,这些用例源于电信行业关键任务超 ...

  10. Java最佳实践–高性能序列化

    在使用Java编程语言时,我们将继续讨论与建议的实践有关的系列文章,我们将讨论并演示如何将对象序列化用于高性能应用程序. 所有讨论的主题均基于用例,这些用例来自于电信行业的关键任务超高性能生产系统的开 ...

最新文章

  1. 这几个 Python 的小技巧,你会么?
  2. OKR让伟大的企业愿景成为可能
  3. java automapper 使用_19.AutoMapper 之开放式泛型(Open Generics)
  4. 【AllJoyn专题】基于AllJoyn和Yeelink的传感器数据上传与指令下行的研究
  5. java类是如何加载的?不知道classLoader和双亲委派,不是一个合格的程序员
  6. 更改centos 7 的默认启动为命令界面
  7. 第五周 Leetcode 99. Recover Binary Search Tree (HARD)
  8. mysql+join的原理,Mysql连接join查询原理知识点
  9. ~~朴素dijkstra算法 (搜索与图论)(附模板题AcWing 849. Dijkstra求最短路 I)
  10. 生成和解析二维码(zxing)
  11. 使用码云或GitHub搭建简单的个人网站
  12. 关于Session、Cookie、Token你知道多少?
  13. PUBG 绝地逃亡 吃鸡压枪宏 彩虹六号压枪宏 Autohotkey
  14. 挖掘机液压控制系统实训QY-JXSX09
  15. RK3399平台开发系列讲解(内核驱动外设篇)6.8、视频解码芯片GM7150驱动的添加
  16. 免费申请ssl证书并部署
  17. WPS Linux版的公式自动编号且右对齐的方法
  18. win10的系统mysql服务器地址,win10的系统mysql服务器地址
  19. Blueprint介绍和使用
  20. Wi-Fi理论基础概述

热门文章

  1. 读取数据快慢的设备_目前在以下各种设备中,读取数据快慢的顺序是内存、硬盘、光盘和软盘。...
  2. Lodash源码解析-------chunk函数
  3. harbor 安装启动遇到的keng
  4. 20165309 实验四 Android程序设计
  5. 测试应该知道的知识-python检查死链
  6. DDG-1000下水
  7. 网宿cdn api 刷新缓存函数
  8. 更换固态硬盘和机械硬盘以及重装系统
  9. 第三章作业题3--队列
  10. Claude Shannon 的“创新性思维”演讲:一个天才揭示如何变得具有创新性