美文网首页异步任务
异步任务优化の(二) 序列化

异步任务优化の(二) 序列化

作者: Yellowtail | 来源:发表于2019-04-04 10:24 被阅读0次

    既然字符串方案行不通,我们回到最初的代码,看看有没有什么思路

    public class AsyncUtils {
    /**
         * <br>定长线程池,目前大小为20
         */
        private static final ExecutorService EXECUTOR_SERVICE = (ExecutorService) Executors.newFixedThreadPool(20);
    
    public static void run(Runnable task){
            EXECUTOR_SERVICE.execute(task);
        }
    

    run 方法里,我们只拿到了一个 Runnable 对象
    这个对象肯定包含了 类名 方法名 参数列表 等参数,不然怎么能被 run 的,对吧

    那么我们如何去获得这些信息呢?

    网上搜了一圈,无果
    自己debug 调试,也没看出啥来

    既然白盒方式行不通,那么黑盒行不行呢?
    也就是:我直接把这个Runnable对象整个存起来,用的时候还原回来用

    序列化 是非常适合 整个存起来 整个概念的

    序列化 第一关

    我们来写下代码

    public static void run(Runnable task){
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
    
        objectOutputStream.writeObject(task);
    
        byte[] byteArray = byteArrayOutputStream.toByteArray();
    }
    

    思路就是把Runnable 对象,通过序列化的方式转为 byte 数组(byte 数组不论存为什么形式都方便)

    实际执行代码的时候,抛出异常,提示 task 不是一个可序列化的对象

    但是我们的 tasklambda 自动生成的,我们也控制不了呀,怎么办呢?

    网上搜了下,找到了解决办法
    这是博客
    )

    我们在调用的时候换下写法就行

    //之前的写法
    AsyncUtils.run( () ->  genGroupUnit(groupId, agentId));
    
    //之后的写法
    AsyncUtils.run( (Runnable & Serializable)() ->  genGroupUnit(groupId, agentId));
    

    加上 (Runnable & Serializable) ,把这个对象强转一下,lambda 就自动对生成的内部匿名类进行序列化了

    用代码测试

    AsyncUtils.run( () ->  System.out.println("Can I be serialized?"));
    

    OK了,反序列化也正常打印
    但是,等等,我们项目中用到异步任务的,难道都是打印吗?

    序列化 第二关

    我们来试试实际代码

    AsyncUtils.run( (Runnable & Serializable)() ->  genGroupUnit(groupId, agentId));
    

    发现还是抛一样的错误
    其实也好理解,genGroupUnit 是调用类的一个方法,序列化的时候,这个类也需要序列化
    那我们让这个类 implements Serializable
    并且自动生成一个 serialVersionUID

    再次运行,咦,依然报错

    序列化 第三关

    网上搜了搜,看到一篇文章

    总结出来的意思就是:
    只要打算序列化一个类,那么这个类本身要实现序列化,
    且如果其成员变量不是 transient类型的,那么也需要实现序列化

    那么问题来了,我们的是 spring 工程,成员变量各种 @Autowired
    Service @Autowired 其他 Service, Service 还 @Autowired DAO

    工作量太大,不太现实

    即使不考虑工作量的问题,最后所有的 Bean 都实现序列化了,
    那么序列化出来的对象,是不是把整个 IOC 给打包了呢?(未尝试,不知道是不是这个场景)
    如果是的话,那这个对象太大了,耗性能,耗IO

    综上, 序列化方案 不适合我的需求
    (只适合微型项目)

    参考

    http://www.importnew.com/24490.html
    https://codeday.me/bug/20170623/25925.html

    相关文章

      网友评论

        本文标题:异步任务优化の(二) 序列化

        本文链接:https://www.haomeiwen.com/subject/hxaxiqtx.html