Java并发处理任务

背景

当一个任务执行时间过长的时候,并且这个任务可以分解成多个独立的任务时,可以使用Java多线程来减少执行时间。

第一版

public static void main(String[] args) throws ExecutionException, InterruptedException {
        func1();
    }

    private static void func1() throws ExecutionException, InterruptedException {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 5, 5, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(2000), new ThreadPoolExecutor.CallerRunsPolicy());
        Callable<Integer> callable = () -> {
            try {
                Thread.sleep(1000L);
                return 1;
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        };
        int n = 10;
        long start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            Future<Integer> submit = threadPool.submit(callable);
            Integer result = submit.get();
            System.out.println(result);
        }
        long end = System.currentTimeMillis();
        System.out.println((end - start) / 1000.0);
        threadPool.shutdown();
    }
}

发现这个版本并没有减少时间,原因是submit.get()会阻塞,会一直等到拿到结果才返回。

第二版

public static void main(String[] args) throws ExecutionException, InterruptedException {
        // func1();
        func2();
    }

    private static void func2() throws ExecutionException, InterruptedException {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 5, 5, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(2000), new ThreadPoolExecutor.CallerRunsPolicy());
        Callable<Integer> callable = () -> {
            try {
                Thread.sleep(2000L);
                return 1;
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        };
        int n = 10;
        List<Future<Integer>> futureList = Lists.newArrayList();
        long start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            futureList.add(threadPool.submit(callable));
        }
        for (Future<Integer> submit : futureList) {
            System.out.println(submit.get());
        }
        long end = System.currentTimeMillis();
        System.out.println((end - start) / 1000.0);
        threadPool.shutdown();
    }
}

可以先把预存结果放到一个列表里,然后统一取结果

第三版

 public static void main(String[] args) throws ExecutionException, InterruptedException {
        // func1(10);
        // func2(100);
        func3(100);
    }

    private static void func3(int n) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 5, 5, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(2000), new ThreadPoolExecutor.CallerRunsPolicy());
        Callable<Integer> callable = () -> {
            try {
                Thread.sleep(1000L);
                return 1;
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        };

        CompletionService<Integer> completionService = new ExecutorCompletionService<>(threadPool);
        long start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            completionService.submit(callable);
        }
        for (int i = 0; i < n; i++) {
            System.out.println(completionService.take().get());
        }
        long end = System.currentTimeMillis();
        System.out.println((end - start) / 1000.0);
        threadPool.shutdown();
    }
}

可以用现成的ExecutorCompletionService

posted @ 2023-07-21 10:24  eaglelihh  阅读(12)  评论(0编辑  收藏  举报