基于Java的快速高效的对象序列化框架,旨在提供快速、高效和易用的API。无论文件、数据库或网络数据Kryo都可以随时完成序列化。Kryo还可以执行自动深拷贝(克隆)、浅拷贝(克隆),这是对象到对象的直接拷贝,非对象→字节→对象的拷贝。支持互相引用,比如类A引用类B,类B引用类A,可以正确地反序列化。
创建一个普通的maven工程,导入kyro依赖
<!-- kryo序列化-->
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo-shaded</artifactId>
<version>4.0.2</version>
</dependency>
多线程场景下的配置
package com.jcl.config;
/**
* 序列化工具(程序调用该接口来实现obj<->byte[]之间的序列化/反序列化)
*/
public interface Serializer{
/**
* 序列化
*/
public void serialize(Object t,byte[] bytes);
/**
* 序列化
*/
public void serialize(Object obj, byte[] bytes, int offset, int count);
/**
* 反序列化
*/
public <T>T deserialize(byte[] bytes);
/**
* 反序列化
*/
public <T>T deserialize(byte[] bytes, int offset, int count);
}
实现类:
package com.jcl.config;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.BeanSerializer;
/**
* 基于kyro的序列化/反序列化工具
*/
public class kryoSerializer implements Serializer
{
// 由于kryo不是线程安全的,所以每个线程都使用独立的kryo
final ThreadLocal<Kryo> kryoLocal = new ThreadLocal<Kryo>()
{
@Override
protected Kryo initialValue()
{
Kryo kryo = new Kryo();
kryo.register(ct, new BeanSerializer<>(kryo, ct));
return kryo;
}
};
// 序列化threadlocal
final ThreadLocal<Output> outputLocal = new ThreadLocal<Output>();
// 反序列化threadlocal
final ThreadLocal<Input> inputLocal = new ThreadLocal<Input>();
private Class<?> ct = null;
public kryoSerializer(Class<?> ct)
{
this.ct = ct;
}
/**
* 序列化
*/
@Override
public void serialize(Object obj, byte[] bytes)
{
Kryo kryo = getKryo();
Output output = getOutput(bytes);
kryo.writeObjectOrNull(output, obj, obj.getClass());
output.flush();
}
/**
* 序列化
*/
@Override
public void serialize(Object obj, byte[] bytes, int offset, int count)
{
Kryo kryo = getKryo();
Output output = getOutput(bytes, offset, count);
kryo.writeObjectOrNull(output, obj, obj.getClass());
output.flush();
}
/**
* 反序列化
*/
@SuppressWarnings("unchecked")
@Override
public <T> T deserialize(byte[] bytes, int offset, int count)
{
Kryo kryo = getKryo();
Input input = getInput(bytes, offset, count);
return (T) kryo.readObjectOrNull(input, ct);
}
/**
* 反序列化
*/
@Override
public <T> T deserialize(byte[] bytes)
{
return deserialize(bytes, 0, bytes.length);
}
/**
* 获取kryo
*/
private Kryo getKryo()
{
return kryoLocal.get();
}
/**
* 获取Output并设置初始数组
*/
private Output getOutput(byte[] bytes)
{
Output output = null;
if ((output = outputLocal.get()) == null)
{
output = new Output();
outputLocal.set(output);
}
if (bytes != null)
{
output.setBuffer(bytes);
}
return output;
}
/**
* 获取Output
*/
private Output getOutput(byte[] bytes, int offset, int count)
{
Output output = null;
if ((output = outputLocal.get()) == null)
{
output = new Output();
outputLocal.set(output);
}
if (bytes != null)
{
output.writeBytes(bytes, offset, count);
}
return output;
}
/**
* 获取Input
*/
private Input getInput(byte[] bytes, int offset, int count)
{
Input input = null;
if ((input = inputLocal.get()) == null)
{
input = new Input();
inputLocal.set(input);
}
if (bytes != null)
{
input.setBuffer(bytes, offset, count);
}
return input;
}
public Class<?> getCt()
{
return ct;
}
public void setCt(Class<?> ct)
{
this.ct = ct;
}
}
package com.jcl.test;
import com.jcl.sample.Simple;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* jdk自带的序列化性能测试
* @author 朝花不迟暮
* @version 1.0
* @date 2020/10/27 20:55
*/
public class OriginalSerializable
{
public static void main(String[] args) throws IOException
{
long start = System.currentTimeMillis();
setSerializableObject();
System.out.println("java原生序列化时间:" + (System.currentTimeMillis() - start) + " ms" );
start = System.currentTimeMillis();
getSerializableObject();
System.out.println("java原生反序列化时间:" + (System.currentTimeMillis() - start) + " ms");
}
public static void setSerializableObject() throws IOException
{
FileOutputStream fo = new FileOutputStream("D:/test.txt");
ObjectOutputStream so = new ObjectOutputStream(fo);
for (int i = 0; i < 100000; i++) {
Map<String,Integer> map = new HashMap<>(2);
map.put("zhang0", i);
map.put("zhang1", i);
so.writeObject(new Simple("zhang"+i,(i+1),map));
}
so.flush();
so.close();
}
public static void getSerializableObject(){
FileInputStream fi;
try {
fi = new FileInputStream("D:/test.txt");
ObjectInputStream si = new ObjectInputStream(fi);
Simple simple =null;
while((simple=(Simple)si.readObject()) != null){
//System.out.println(simple.getAge() + " " + simple.getName());
}
fi.close();
si.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
//e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
package com.jcl.test;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.KryoException;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.jcl.sample.Simple;
import org.objenesis.strategy.StdInstantiatorStrategy;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* https://mp.weixin.qq.com/s?__biz=MzU0NDA2MjY5Ng==&mid=2247490672&idx=1&sn=4a1e57f8fc63de2ba611e90e87224766&chksm=fb00b1f7cc7738e18cea6a8d70748a5172f30dbab537121f72ec1d4f90398c905abeebb78dbd&mpshare=1&scene=23&srcid=10271rQmC5mYRMWMuRQnzO2R&sharer_sharetime=1603799292215&sharer_shareid=7da19e92911183dd19f355111ebfa2dc#rd
* @author 朝花不迟暮
* @version 1.0
* @date 2020/10/27 21:01
*/
public class KyroSerializable
{
public static void main(String[] args) throws IOException
{
long start = System.currentTimeMillis();
setSerializableObject();
System.out.println("Kryo 序列化时间:" + (System.currentTimeMillis() - start) + " ms" );
start = System.currentTimeMillis();
getSerializableObject();
System.out.println("Kryo 反序列化时间:" + (System.currentTimeMillis() - start) + " ms");
}
public static void setSerializableObject() throws FileNotFoundException{
Kryo kryo = new Kryo();
kryo.setReferences(false);
kryo.setRegistrationRequired(false);
kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
kryo.register(Simple.class);
Output output = new Output(new FileOutputStream("D:/file1.txt"));
for (int i = 0; i < 100000; i++) {
Map<String,Integer> map = new HashMap<String, Integer>(2);
map.put("zhang0", i);
map.put("zhang1", i);
kryo.writeObject(output, new Simple("zhang"+i,(i+1),map));
}
output.flush();
output.close();
}
public static void getSerializableObject(){
Kryo kryo = new Kryo();
kryo.setReferences(false);
kryo.setRegistrationRequired(false);
kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
Input input;
try {
input = new Input(new FileInputStream("D:/file1.txt"));
Simple simple =null;
while((simple=kryo.readObject(input, Simple.class)) != null){
//System.out.println(simple.getAge() + " " + simple.getName() + " " + simple.getMap().toString());
}
input.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch(KryoException e){
}
}
}
从效率上来看,提升了十倍!如果想详细了解点链接了解详情