protostuff序列化集合的问题(反序列化时的java.util.ConcurrentModificationException)

之前写过一篇关于JDK原始支持的Serializable接口序列化与Google的Protostuff序列化两种技术的比较(http://blog.csdn.net/canot/article/details/53750443)。Protostuff序列化的性能,空间利用率远高于Serializable接口。基于这些原因,最近在做
MyBatis开发的过程中使用二级缓存的时候就使用了Protostuff与Redis数据库来做序列化。
Protostuff完成一个序列化与反序列化的代码比较简单:
Maven依赖

      <dependency>
            <groupId>io.protostuff</groupId>
            <artifactId>protostuff-core</artifactId>
            <version>1.4.4</version>
        </dependency>
        <dependency>
            <groupId>io.protostuff</groupId>
            <artifactId>protostuff-runtime</artifactId>
            <version>1.4.4</version>
        </dependency>

核心代码

//制定要序列化的对象
private static RuntimeSchema<Person> schema = RuntimeSchema.createFrom(Person.class);
/** *序列化 */
Person crab = new Person();  
crab.setName("kaka");  
//参数三缓冲器
byte[] bytes = ProtostuffIOUtil.toByteArray(crab,schema,LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
/** *反序列化 */
// 空对象
Person newCrab = schema.newMessage();
ProtostuffIOUtil.mergeFrom(bytes,newCrab,schema);
System.out.println("Hi, My name is " + newCrab.getName());

上述代码是没有任何问题的。然后当使用在MyBatis二级缓存上的时候,情况有一点点不一样。
众所周知,二级缓存只使用在select语句上,而select语句查询出来的数据是个List,并且是个ArrayList。
那么想当然的将Protostuff的schema制定为ArrayList

    private static RuntimeSchema<ArrayList> schema = RuntimeSchema.createFrom(ArrayList.class);

如果指定为List接口编译都通过不了,schema无法指定为接口或抽象类
然后的操作无非就是序列化,反序列化,在我打印日志查看的时候,序列化过程是没有如何问题的。但当我开始执行反序列化操作,要将byte数组还原为ArrayList集合的时候,编译器抛出了一个异常

java.util.ConcurrentModificationException

对于Java集合比较熟悉的朋友应该知道这是个并发操作异常,出现的情况是在编辑集合的过程中对集合进行了增删操作。当时我的解决办法是定义一个类,一个专门做为Protostuff schema的类,它只包含一个字段ArrayList

class CacheEntry{
    private List<Seckill> seckills;
    public CacheEntry(List<Seckill> seckills){
        this.seckills=seckills;
    }
    public List<Seckill> getSeckills() {
        return seckills;
    }

    public void setSeckills(List<Seckill> seckills) {
        this.seckills = seckills;
    }
}

然后将select出来的数据放入这个类的实体中,对这个实体做序列化,反序列化操作。

    private static RuntimeSchema<CacheEntry> schema = RuntimeSchema.createFrom(CacheEntry.class);

完美运行。

你可能感兴趣的:(mybatis,序列化,二级缓存,protostuff)