日常隨筆之線程池invokeAll使用風險


話不多說直接上代碼,invokeAll的使用方式如下圖

public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        List<Callable<Integer>> tasks = new ArrayList<>();
        for( int i = 0; i < 10; i++) {
            tasks.add(()->{
                Random random = new Random();
                int second = random.nextInt(10);
                Thread.sleep(second * 1000) ;
                return second;
            });
        }
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        List<Future<Integer>> futures = executorService.invokeAll(tasks);
        for( int i = 0; i < futures.size(); i++) {
            System.out.println(futures.get(i).get());
        }

        executorService.shutdown();
    }
}

invokeAll的作用是:等待所有的任務執行完成后統一返回。

這里與大家分享的是:如果executorService是公共線程池慎用,如果這時候有另外一個請求也不斷地往線程池里不斷地方任務,這時候這個請求是不是就一直不停的阻塞了。

推薦寫法如下:

public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException, ExecutionException {
List<Future<Integer>> tasks = new ArrayList<>();

ExecutorService executorService = Executors.newFixedThreadPool(10);
for( int i = 0; i < 10; i++) {
Future<Integer> f = executorService.submit(() -> {
Random random = new Random();
int second = random.nextInt(10);
Thread.sleep(second * 1000);
return second;
});
tasks.add(f);
}



for( int i = 0; i < tasks.size(); i++) {
System.out.println(tasks.get(i).get());
}

executorService.shutdown();
}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM