Java使用xstream序列化线程池任务

Mars 2020年05月24日 23次浏览

Java使用xstream序列化线程池任务

准备

  • 引入序列化框架xstream

     <!--xstream序列化框架-->
            <dependency>
                <groupId>com.thoughtworks.xstream</groupId>
                <artifactId>xstream</artifactId>
                <version>1.4.11.1</version>
            </dependency>
    
  • 编写测试需要的类

static interface SerializableRunnable extends Serializable,  Runnable {

}

static class TempObj {

        //private static final long serialVersionUID = 4917457758902275018L;

        public String name;

        //private Integer age;
    }
    static class A {
        public static void a() {
            System.out.println("我是静态方法a.........");
        }
    }
    static class B {
        public void b() {
            System.out.println("我是成员方法b.........");
        }
    }
    static class C {
        public void c() {
            System.out.println("我是成员方法c.........");
        }
    }
    interface D {
        void d();
    }
    interface E {
        void e();
    }
  • 包装线程池

    static class Pool {
            private ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
    
    
            /**
             * 等同于
             * <pre>
             *      Runnable runnable1 = (Serializable & Runnable) () -> System.out.println("to do..");
             * </pre>
             * 两种方式都可以让任务可序列化
             */
            public void execute(SerializableRunnable runnable) {
                pool.execute(runnable);
            }
    
            public List<Runnable> shutdownNow() {
                return pool.shutdownNow();
            }
    
        }
    

测试

  • 编写测试代码

    /**
     * 测试序列化线程中断时返回的任务是否能继续执行
     */
    public static void testPool() throws Exception {
        Pool pool = new Pool();
        IntStream.range(0, 10).forEach(i -> pool.execute(createSerializableRunnable(1, i)));

        TimeUnit.MILLISECONDS.sleep(900);
        List<Runnable> runnables = pool.shutdownNow();

        String s = XStreamTest.beanToXml(runnables.get(0));
        System.out.println("序列化线程池任务:\n" + s);
        SerializableRunnable newTask = (SerializableRunnable) XStreamTest.xmlToBean(s);
        System.out.println("反序列线程池任务成功.........\n\n");
        TimeUnit.SECONDS.sleep(1);

        Pool pool1 = new Pool();
        pool1.execute(newTask);
        TimeUnit.DAYS.sleep(1);
    }


    /**
     * 创建一个序列化任务
     *
     * @param waitSeconds 延时多少秒
     * @param sort        当前是第几个任务
     * @return 序列化任务
     */
    public static SerializableRunnable createSerializableRunnable(long waitSeconds, int sort) {
        TempObj tempObj = new TempObj();
        tempObj.name = "xstream temp obj";
        C c = new C();
        D d = new D() {
            @Override
            public void d() {
                System.out.println("我是内部类d............");
            }
        };
        SerializableRunnable runnable = () -> {
            System.out.println("我是第" + sort + "个任务  " + tempObj.name);
            if (waitSeconds != 0) {
                try {
                    TimeUnit.SECONDS.sleep(waitSeconds);
                } catch (InterruptedException e) {
                    System.out.println("任务被中断.....");
                }
            }
            IntStream.range(0, 5).forEach(System.out::println);
            A.a();
            new B().b();
            c.c();
            d.d();
            new E() {
                @Override
                public void e() {
                    System.out.println("我是内部类e............");
                }
            };
        };
        return runnable;
    }

    public static void main(String[] args) throws Exception {
        //testSimpleObj();
        //testLambdaObj();

        testPool();
    }
  • 反序列化部分输出如下

    反序列线程池任务成功.........
    
    
    我是第3个任务  xstream temp obj
    0
    1
    2
    3
    4
    我是静态方法a.........
    我是成员方法b.........
    我是成员方法c.........
    我是内部类d............
    
    

结论

  • 线程池提交的任务类型为lambda创建的,则必须实现序列化接口,否则无法序列化
  • 非lambda创建的对象,包括内部类,通过xstream的方式都可以序列化
  • xstream可以循环序列化,即序列化对象里面包含其余对象,包含的对象未实现序列化接口都可以序列化