家族战队|Java 序列化界新贵 kryo 和熟悉的“老大哥”( 二 )
首先 , 创建 Kryo 对象池 , 通过重写 Pool 接口的 create 方法 , 便可创建出自定义配置的对象池 。
private static final Pool当需要使用 kryo 时 , 调用 kryoPool.obtain() 方法即可 , 使用完毕后再调用 kryoPool.free(kryo) 归还对象 , 就完成了一次完整的租赁使用 。
public static byte[] serialize(Object obj) {Kryo kryo = kryoPool.obtain();// 使用 Output 对象池会导致序列化重复的错误(getBuffer返回了Output对象的buffer引用)try (Output opt = new Output(1024, -1)) {kryo.writeClassAndObject(opt, obj);opt.flush();return opt.getBuffer();}finally {kryoPool.free(kryo);}}对象池技术是所有并发安全方案中性能最好的 , 只要对象池大小评估得当 , 就能在占用极小内存空间的情况下完美解决并发安全问题 。 这也是 PowerJob 诞生初期使用的方案 , 直到...PowerJob 正式推出容器功能后 , 才不得不放弃该完美方案 。
在容器模式下 , 使用 kryo 对象池计算会有什么问题呢?这里简单给大家提一下 , 至于看不看得懂 , 就要看各位造化了~
PowerJob 容器功能指的是动态加载外部代码进行执行 , 为了进行隔离 , PowerJob 会使用单独的类加载器完成容器中类的加载 。 因此 , 每一个 powerjob-worker 中存在着多个类加载器 , 分别是系统类加载器(负责项目的加载)和每个容器自己的类加载器(加载容器类) 。 序列化工具类自然是 powerjob-worker 的一部分 , 随 powerjob-worker 的启动而被创建 。 当 kryo 对象池被创建时 , 其使用的类加载器是系统类加载器 。 因此 , 当需要序列化/反序列化容器中的类时 , kryo 并不能从自己的类加载器中获取相关的类信息 , 妥妥的抛出 ClassNotFoundError!
因此 , PowerJob 在引入容器技术后 , 只能退而求其次 , 采取了第二种并发安全方法:ThreadLocal 。
1.4 ThreadLocalThreadLocal 是一种典型的牺牲空间来换取并发安全的方式 , 它会为每个线程都单独创建本线程专用的 kryo 对象 。 对于每条线程的每个 kryo 对象来说 , 都是顺序执行的 , 因此天然避免了并发安全问题 。 创建方法如下:
private static final ThreadLocal之后 , 仅需要通过 *kryoLocal*.get() 方法从线程上下文中取出对象即可使用 , 也算是一种简单好用的方案 。 (虽然理论性能比对象池差不少)
二、老牌框架:Jackson大名鼎鼎的 Jackson 相信大家都听说过 , 也是很多项目的御用 JSON 序列化/反序列化框架 。 在 PowerJob 中 , 本着不重复造轮子的原则 , 在 akka 通讯层 , 使用了 jackson-cbor 作为默认的序列化框架 。
推荐阅读
- 爱游戏的甲子|G2战队“杀人诛心”,阿P用两句话嘲讽LCK战队,DWG被逼入绝境
- 老猫要有腹肌|AG超玩会战队人气位列榜首,久诚人气不及一诺
- 财经女记者部落|老板却坚决拒绝粉丝经济,选手只招大学生,电竞战队斩获《炉石传说》联赛冠军
- 电竞小肥仔|和平精英:战队专属皮肤推荐合集,最后JDE队服堪比至尊金龙!
- 海军陆战队|美两大军种争资源,抢着对抗中国?美专家:对手导弹太多,应互补
- 4am战队|绝地求生秋季赛决赛第一日-rng登顶,4am稳定,ifty、tianba拉闸
- 麻醉说游戏|KPL秋季赛一半赛程已过!这两支战队即将提前锁定胜者组?
- 指尖上的王者|KPL五周T队排名,“天王级”战队只有两个,TS被踢出队列
- tes战队|“给阿水下了毒”就在今天,Rookei对TES让二追三做出评价,差点吓跑了!
- dwg战队|“打LCK胜率高有秘诀”就在今天,G2晋级4强全员喊话DWG,你们不是我对手!
