前言 kryo是个高效的java序列化反序列化库,目前Twitter、yahoo、Apache、strom等等在使用该技术,比如Apache的spark、hive等大数据领域用的较多。为什么使用kryo而不是其他? 因为性能足够好。比kyro更高效的序列化库就只有google的protobuf了(而且两者性能很接近),protobuf有个缺点就是要传输的每一个类的结构都要生成对应的proto文件(也可以都放在同一个proto文件中,如果考虑到扩展性的话,不建议放在一个proto文件中),如果某个类发生修改,还得重新生成该类对应的proto文件;另外考虑到项目中用的全部是java技术栈,不存在不同编程语言间的兼容性问题,因此最终采用了kryo作为序列化库。使用场景 (数据交换或数据持久化)比如使用kryo把对象序列化成字节数组发送给消息队列或者放到redis等nosql中等等应用场景。 注意:由于kryo不是线程安全的,针对多线程情况下的使用,要对kryo进行一个简单的封装设计,从而可以多线程安全的使用序列化和反序列化序列化和反序列化接口设计序列化工具(程序调用该接口来实现objbyte〔〕之间的序列化反序列化)authoreguidpublicinterfaceSerializer{序列化paramtparambytespublicvoidserialize(Objectt,byte〔〕bytes);序列化paramobjparambytesparamoffsetparamcountpublicvoidserialize(Objectobj,byte〔〕bytes,intoffset,intcount);反序列化parambytes字节数组returnTTpublicTTdeserialize(byte〔〕bytes);反序列化parambytesparamoffsetparamcountreturnpublicTTdeserialize(byte〔〕bytes,intoffset,intcount);}使用kryo实现上面的接口基于kyro的序列化反序列化工具authoreguidpublicclasskryoSerializerimplementsSerializer{由于kryo不是线程安全的,所以每个线程都使用独立的kryofinalThreadLocalKryokryoLocalnewThreadLocalKryo(){OverrideprotectedKryoinitialValue(){KryokryonewKryo();kryo。register(ct,newBeanSerializer(kryo,ct));returnkryo;}};finalThreadLocalOutputoutputLocalnewThreadLocalOutput();finalThreadLocalInputinputLocalnewThreadLocalInput();privateClasslt;?ctnull;publickryoSerializer(Classlt;?ct){this。ctct;}publicClasslt;?getCt(){returnct;}publicvoidsetCt(Classlt;?ct){this。ctct;}Overridepublicvoidserialize(Objectobj,byte〔〕bytes){KryokryogetKryo();OutputoutputgetOutput(bytes);kryo。writeObjectOrNull(output,obj,obj。getClass());output。flush();}Overridepublicvoidserialize(Objectobj,byte〔〕bytes,intoffset,intcount){KryokryogetKryo();OutputoutputgetOutput(bytes,offset,count);kryo。writeObjectOrNull(output,obj,obj。getClass());output。flush();}获取kryoparamtreturnprivateKryogetKryo(){returnkryoLocal。get();}获取Output并设置初始数组parambytesreturnprivateOutputgetOutput(byte〔〕bytes){Outputoutputnull;if((outputoutputLocal。get())null){outputnewOutput();outputLocal。set(output);}if(bytes!null){output。setBuffer(bytes);}returnoutput;}获取OutputparambytesreturnprivateOutputgetOutput(byte〔〕bytes,intoffset,intcount){Outputoutputnull;if((outputoutputLocal。get())null){outputnewOutput();outputLocal。set(output);}if(bytes!null){output。writeBytes(bytes,offset,count);}returnoutput;}获取InputparambytesparamoffsetparamcountreturnprivateInputgetInput(byte〔〕bytes,intoffset,intcount){Inputinputnull;if((inputinputLocal。get())null){inputnewInput();inputLocal。set(input);}if(bytes!null){input。setBuffer(bytes,offset,count);}returninput;}SuppressWarnings(unchecked)OverridepublicTTdeserialize(byte〔〕bytes,intoffset,intcount){KryokryogetKryo();InputinputgetInput(bytes,offset,count);return(T)kryo。readObjectOrNull(input,ct);}OverridepublicTTdeserialize(byte〔〕bytes){returndeserialize(bytes,0,bytes。length);}测试一下kryo的序列化和反序列化 为什么使用纳秒,而不用毫秒?与java原生的序列化反序列化要耗时几毫秒不同,kryo序列化和反序列化太快了,单个对象的序列化反序列化速度都在0。0x毫秒左右(如果电脑性能更好的话,会更快)SerializersernewkryoSerializer(Msg。class);for(inti0;i10;i){MsgmsgnewMsg();msg。setVersionflag(newbyte〔〕{1,2,3});msg。setCrccode((short)1);msg。setMsgbody(newbyte〔〕{123,123,123,43,42,1,12,45,57,98});byte〔〕bytesnewbyte〔300〕;longstartSystem。nanoTime();ser。serialize(msg,bytes);System。err。println(序列化耗时:(System。nanoTime()start));System。out。println(msg);System。out。println(Arrays。toString(bytes));Msgnewmsgnull;startSystem。nanoTime();newmsgser。deserialize(bytes);System。err。println(反序列化耗时:(System。nanoTime()start));System。out。println(newmsg);} 作者:eguid1 链接:https:juejin。cnpost6953556788062978079