Java多任務併發:如何判斷線程池中的任務都已經執行完畢?

前言:

多線程併發,我們往往採用線程池來管理併發的線程。但是,我們往往有這樣的需要:要求在線程池中的任務都完成後才能執行後續的任務,或者需要任務都完成後釋放資源或向數據庫寫入狀態。這些都需要我們判斷線程池的任務是否都已經完成。

判斷線程池中的任務是否全部完成,方式有不少,這裡我來整理一下。

一、使用線程池的原生函數isTerminated();

優點:操作簡便;

缺點:需要主線程阻塞;

executor提供一個原生函數isTerminated()來判斷線程池中的任務是否全部完成。全部完成返回true,否則返回false。

栗子:

package my.thread.test;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

class AnyTask implements Runnable{

public void run() {

try {

Thread.sleep(3000);

System.out.println("普通任務執行執行完畢!");

}catch(Exception e) {

e.printStackTrace();

}

}

}

class EndTask {

public void taskRun() {

try {

System.out.println("開始執行最終任務");

}catch(Exception e) {

e.printStackTrace();

}

}

}

public class TeminatedTest {

public static void main(String[] args) {

try {

ExecutorService exector = Executors.newFixedThreadPool(7);

for(int i =0;i<10;i++) {

AnyTask anyTask = new AnyTask();

exector.execute(anyTask);

}

exector.shutdown();

while(true) {

if(exector.isTerminated()) {

EndTask endTask = new EndTask();

endTask.taskRun();

break;

}else {

Thread.sleep(3000);

}

}

}catch(Exception e) {

e.printStackTrace();

}

}

}

操作很方便,但要求主線程阻塞,這樣對接口化編程很不友好。

二、使用CountDownLatch:

優點:操作相對簡便,可以把等待線程池中任務完成後的後續工作做成任務,同樣放到線程池中運行,簡單來說,就是可以控制線程池中任務執行的順序。

缺點:

(1)需要提前知道任務的數量。

(2)大規模任務下影響併發的性能(可能)

原理:其工作原理是賦給CountDownLatch一個計數值,普通的任務執行完畢後,調用countDown()執行計數值減一。最後執行的任務在調用方法的開始調用await()方法,這樣整個任務會阻塞,直到這個計數值(Count)為零,才會繼續執行。


分享到:


相關文章: