高性能多任务处理实践之CompletionService

多任务处理是提升系统性能的理想选择,下面给出两种实现方案,分别介绍了ExecutorService结合Callable接口利用线程池提交任务,以及更高效的CompletionService接口实现多任务处理实践。

package thread;

import java.util.concurrent.*;

public class Refresh {
    private final ExecutorService executorService = Executors.newCachedThreadPool();
    private static int result = 2;

    public void bussiness(){
        Callable<Integer> task = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int sum = 0;
                for(int i=0; i < 10; i++){
                    sum += i;
                }
                Thread.sleep(10000);
                return sum;
            }
        };

        long start = System.currentTimeMillis();
        Future<Integer> submit = executorService.submit(task);

        System.out.println("do other work");
        executorService.execute(new LoadClass());
        System.out.println("接着干");


        try {
            this.result = submit.get();
            System.out.println("等待了" + (System.currentTimeMillis() - start) / 1000 + "s");
        } catch (InterruptedException e) {
            Thread.currentThread().isInterrupted();
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    private static class LoadClass implements Runnable{

        @Override
        public void run() {
            while (result == 2){
                try {
                    Thread.sleep(1000);
                    System.out.println("我在等你不再2了");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    e.printStackTrace();
                }
            }
            System.out.println("终于不2了");
        }
    }

    public static void main(String[] args) {
        new Refresh().bussiness();
    }


}

这里写图片描述

上面这种实现方式虽然能多个任务一起处理,但是因为主线程结果要依赖每一个(所有)任务返回结果(Future),所以会多出时间去等待所有结果,造成没必要的等待,对系统性能造成影响。

下面给出另外一种方式

package thread;

import java.util.concurrent.*;

public class RefreshOther {
    private final ExecutorService executorService = Executors.newCachedThreadPool();
    private static int result = 0;

    public void bussiness(){
        CompletionService<Integer> completionService = new ExecutorCompletionService<>(executorService);

        int time=0;
        for(int i=0; i<10; i++){
            int finalK = i;
            time+=1000; // 睡眠时间,模拟延迟每一个任务返回结果,体现异步更新结果
            int finalTime = time;
            completionService.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    return new LoadClass(finalK, finalTime).print();
                }
            });
        }

        System.out.println("do other work start");
        Bussiness bussiness = new Bussiness();
        bussiness.setInput(0);
        LoadClass loadClass = new LoadClass(bussiness);
        executorService.execute(loadClass); // 这里依赖上面任务返回的值

        for(int i=0; i<10; i++){
            try {
                Future<Integer> take = completionService.take();
                Thread.sleep(3000); // 这里为了确保后面能够拿到每一个任务返回的结果
                result = take.get();
                bussiness.setInput(result);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }

    class LoadClass implements Runnable{
        private long time;
        private int i;
        private Bussiness tm;

        LoadClass(Bussiness temp){
            this.tm = temp;
        }

        LoadClass(int i, long time){
            this.time = time;
            this.i = i;
        }

        private int print(){
            try {
                Thread.sleep(this.time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return this.i;
        }

        @Override
        public void run() {
            int now = -1;
            while (true){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(tm.getInput() != now){
                    System.out.println("我现在变为:" + tm.getInput());
                    now = tm.getInput();
                }
                if(tm.getInput() == 9) // 特殊处理让程序结束
                    break;
            }
            System.out.println("-------- the end ---------");
        }
    }

    public static void main(String[] args) {
        new RefreshOther().bussiness();
    }

}
package thread;

public class Bussiness {
    private Integer input;
    public Integer getInput() {
        return input;
    }
    public void setInput(Integer input) {
        this.input = input;
    }
}

程序执行结果如下
这里写图片描述

上面的方案是利用了CompletionService能实现任务异步处理特性,任务处理和提交同时进行,并且让Future接受每一个任务执行结果。由于任务能够异步处理返回,因此没有产生多余的等待时间,较上一种实现方案,使用CompletionService来实现性能更高、更有效。

猜你喜欢

转载自blog.csdn.net/huangdi1309/article/details/79305195