1.我们知道在java中有序列化的概念
序列化的过程就是将对象转变成字节码,反序列化即是从字节码转换成对象的过程一般情况下要求实现Serializable接口,此接口中没有定义任何成员,只是起到标记对象是否可以被序列化的作用。为何需要有序列化呢?一方面是为了存储在磁盘中,另一个作用就是作为网络远程传输的内容。
2.java中实现序列化 //对象转成字节码
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(VoUtil.getUser());
byte []bytes = byteArrayOutputStream.toByteArray();
outputStream.close();
//字节码转换成对象
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);
User result = (User) inputStream.readObject();
inputStream.close();
附实验代码:
public class JsonUtil {
public static JSON serializer(T t){
return (JSON)JSONObject.toJSON(t);
}
public static T deserializer(JSON json,Class c) {
return JSONObject.parseObject(json.toJSONString(),c);
}
}
package com.xps.serilizer.protostuff;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
/**
* Created by xiongps on 2018/5/23.
*/
public class ProtostuffUtil {
public static byte[] serializer(T t){
Schema schema = RuntimeSchema.getSchema(t.getClass());
return ProtostuffIOUtil.toByteArray(t,schema,
LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
}
public static T deserializer(byte []bytes,Class c) {
T t = null;
try {
t = c.newInstance();
Schema schema = RuntimeSchema.getSchema(t.getClass());
ProtostuffIOUtil.mergeFrom(bytes,t,schema);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return t;
}
}
package com.xps.serilizer.kryo;
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 com.xps.serilizer.vo.User;
import com.xps.serilizer.vo.VoUtil;
import org.objenesis.strategy.StdInstantiatorStrategy;
import java.io.*;
/**
* Created by xiongps on 2018/5/23.
*/
public class SerilizerTestUtil {
private static final ThreadLocal kryos = new ThreadLocal() {
protected 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;
}
};
private static KryoFactory factory = new KryoFactory() {
@Override
public Kryo create() {
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;
}
};
private static KryoPool pool = new KryoPool.Builder(factory).softReferences().build();
public static void kryoSeriAsFile(){
Kryo kryo = kryos.get();
Output output = null; Input input = null;
try {
output = new Output(new FileOutputStream("F:\\test\\file.bin"));
User user = VoUtil.getUser();
kryo.writeObject(output, user);
output.flush();
output.close();
input = new Input(new FileInputStream("F:\\test\\file.bin"));
User userAsOut = kryo.readObject(input, User.class);
System.out.println(userAsOut.getUserNm());
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
input.close();
}
}
public static void kryoSeriAsByte(){
Kryo kryo = kryos.get();
byte[] bytes = null;
long st = System.nanoTime();
//kryo.register(User.class,new JavaSerializer());
try {
ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();
Output output = new Output(byteArrayOutputStream);
//kryo.writeObject(output,getUser());
kryo.writeClassAndObject(output,VoUtil.getUser());
output.flush();
output.close();
bytes = byteArrayOutputStream.toByteArray();
ByteArrayInputStream byteArrayInputStream = new
ByteArrayInputStream(bytes);
Input input = new Input(byteArrayInputStream);
//User result = (User) kryo.readObject(input,User.class);
User result = (User) kryo.readClassAndObject(input);
input.close();
System.out.println(result.getUserNm()+"kryo time:"+(System.nanoTime()-st));
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
public static void kryoGetAsPoolSeriAsByte(){
Kryo kryo = pool.borrow();
byte[] bytes = null;
long st = System.nanoTime();
//kryo.register(User.class,new JavaSerializer());
try {
ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();
Output output = new Output(byteArrayOutputStream);
//kryo.writeObject(output,getUser());
kryo.writeClassAndObject(output,VoUtil.getUser());
output.flush();
output.close();
bytes = byteArrayOutputStream.toByteArray();
ByteArrayInputStream byteArrayInputStream = new
ByteArrayInputStream(bytes);
Input input = new Input(byteArrayInputStream);
//User result = (User) kryo.readObject(input,User.class);
User result = (User) kryo.readClassAndObject(input);
input.close();
System.out.println(result.getUserNm()+"kryo1 time:"+(System.nanoTime()-st));
} catch (Exception e) {
e.printStackTrace();
} finally {
pool.release(kryo);
}
}
public static void kryoGetAsPoolSeriAsByte2(){
long st = System.nanoTime();
try {
User ret = pool.run(new KryoCallback() {
@Override
public User execute(Kryo kryo) {
ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();
Output output = new Output(byteArrayOutputStream);
//kryo.writeObject(output,getUser());
kryo.writeClassAndObject(output,VoUtil.getUser());
output.flush();
output.close();
byte[] bytes = null;
bytes = byteArrayOutputStream.toByteArray();
ByteArrayInputStream byteArrayInputStream = new
ByteArrayInputStream(bytes);
Input input = new Input(byteArrayInputStream);
//User result = (User) kryo.readObject(input,User.class);
User result = (User) kryo.readClassAndObject(input);
input.close();
return result;
}
});
System.out.println(ret.getUserNm()+"kryo2 time:"+(System.nanoTime()-st));
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
public static void javaSerilizer(){
byte[] bytes = null;
long st = System.nanoTime();
try {
ByteArrayOutputStream byteArrayOutputStream = new
ByteArrayOutputStream();
ObjectOutputStream outputStream = new
ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(VoUtil.getUser());
outputStream.close();
bytes = byteArrayOutputStream.toByteArray();
ByteArrayInputStream byteArrayInputStream = new
ByteArrayInputStream(bytes);
ObjectInputStream inputStream = new
ObjectInputStream(byteArrayInputStream);
User result = (User) inputStream.readObject();
inputStream.close();
System.out.println(result.getUserNm()+"java time:"+(System.nanoTime()-st));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
}
}
}
package com.xps.serilizer.fst;
import org.nustaq.serialization.FSTConfiguration;
/**
* Created by xiongps on 2018/5/23.
*/
public class FstUtil {
private static ThreadLocal confs = new ThreadLocal(){
public FSTConfiguration initialValue() {
return FSTConfiguration.createDefaultConfiguration();
}
};
private static FSTConfiguration getFST(){
return confs.get();
}
public static byte[] serializer(T t){
return getFST().asByteArray(t);
}
public static T deserializer(byte []bytes,Class c) {
return (T)getFST().asObject(bytes);
}
}
运行结果:
package com.xps.serilizer.protostuff;
import com.alibaba.fastjson.JSON;
import com.xps.serilizer.fst.FstUtil;
import com.xps.serilizer.json.JsonUtil;
import com.xps.serilizer.kryo.SerilizerTestUtil;
import com.xps.serilizer.vo.User;
import com.xps.serilizer.vo.VoUtil;
import java.util.Arrays;
/**
* Created by xiongps on 2018/5/23.
*/
public class ProtostuffTest {
public static void main( String[] args )
{
long javaTime = 0l;
long kryoTime = 0l;
long protostuffTime = 0l;
long fstTime = 0l;
long jsonTime = 0l;
int loopCnt = 100;
boolean isAdd = false;
for(int i=0;i0?true:false;
long t0 = System.nanoTime();
SerilizerTestUtil.javaSerilizer();
if(isAdd) {
javaTime +=(System.nanoTime()-t0);
}
long tt = System.nanoTime();
SerilizerTestUtil.kryoGetAsPoolSeriAsByte();
if(isAdd) {
kryoTime +=(System.nanoTime()-tt);
}
long t = System.nanoTime();
byte []bytes = ProtostuffUtil.serializer(VoUtil.getUser());
User user = ProtostuffUtil.deserializer(bytes,User.class);
if(isAdd) {
protostuffTime += (System.nanoTime()-t);
}
//System.out.println(user.getUserNm()+"proto time:"+(System.nanoTime() -t));
long t2 = System.nanoTime();
byte []bytes2 = FstUtil.serializer(VoUtil.getUser());
user = FstUtil.deserializer(bytes2,User.class);
if(isAdd) {
fstTime += (System.nanoTime()-t2);
}
//System.out.println(user.getUserNm()+"fst time:"+(System.nanoTime() -t2));
long t3 = System.nanoTime();
JSON json = JsonUtil.serializer(VoUtil.getUser());
user = JsonUtil.deserializer(json,User.class);
if(isAdd) {
jsonTime += (System.nanoTime()-t3);
}
//System.out.println(user.getUserNm()+"json time:"+(System.nanoTime() -t3));
}
System.out.println("循环"+loopCnt+"次,共用时(毫秒):\n"+"javaTime :"+javaTime/1000000.0+
"\nkryoTime :"+kryoTime/1000000.0+
"\nprotostuffTime:"+protostuffTime/1000000.0+
"\nfstTime :"+fstTime/1000000.0+
"\njsonTime :"+jsonTime/1000000.0);
}
}
循环10次,共用时(毫秒):
javaTime :3.978881
kryoTime :1.041478
protostuffTime:0.468708
fstTime :0.860724
jsonTime :1.340264
循环100次,共用时(毫秒):
javaTime :42.63442
kryoTime :12.16559
protostuffTime:5.23874
fstTime :9.432315
jsonTime :16.042395
循环1000次,共用时(毫秒):
javaTime :335.050281
kryoTime :114.677958
protostuffTime:54.912879
fstTime :109.997724
jsonTime :151.238032