当前位置:网站首页>How to judge that the thread pool has completed all tasks?
How to judge that the thread pool has completed all tasks?
2022-07-05 10:11:00 【A bird carved in the desert】
A lot of scenarios , We need to wait for all tasks of the thread pool to be executed , Then proceed to the next step . For threads Thread Come on , Well done , Add one more join The solution is solved , However, the judgment of thread pool is more troublesome .
We provide 4 A method to judge whether thread pool tasks have been executed :
- Use isTerminated Methods to judge .
- Use getCompletedTaskCount Methods to judge .
- Use CountDownLatch Judge .
- Use CyclicBarrier Judge .
Let's take a look at one by one .
The problem of not judging
If you don't judge whether the thread pool has been executed , The following problems will occur , As shown in the following code :
import java.util.Random;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolCompleted {
public static void main(String[] args) {
// Creating a thread pool
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 20,
0, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1024));
// Add tasks
addTask(threadPool);
// Print the results
System.out.println(" Thread pool task execution completed !");
}
/**
* Add tasks to the thread pool
*/
private static void addTask(ThreadPoolExecutor threadPool) {
// Total tasks
final int taskCount = 5;
// Add tasks
for (int i = 0; i < taskCount; i++) {
final int finalI = i;
threadPool.submit(new Runnable() {
@Override
public void run() {
try {
// Random sleep 0-4s
int sleepTime = new Random().nextInt(5);
TimeUnit.SECONDS.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format(" Mission %d Execution completed ", finalI));
}
});
}
}
}
The results of the above procedures are as follows :
As can be seen from the above execution results , The program prints first “ Thread pool task execution completed !”, Then it is still executing the task of thread pool in succession , The result of this chaotic execution sequence , Not what we expected . The result we want is when all the tasks are completed , Re print “ Thread pool task execution completed !” Information about .
The reason for the above problem is that the main thread main, And thread pool are executed concurrently , So when the thread pool is not finished ,main The print result code of the thread has been executed . I want to solve this problem , You need to print the results before , First, judge whether the tasks of the thread pool have been fully executed , If not, wait for the task to be executed before printing the results .
Method 1:isTerminated
We can take advantage of the termination state of the thread pool (TERMINATED) To determine whether all the tasks of the thread pool have been executed , But I want the state of the thread pool to change , We need to call the thread pool shutdown Method , Otherwise, the thread pool will always be in RUNNING Running state , Then there is no way to use the termination status to judge whether the task has been completely executed , Its implementation code is as follows :
import java.util.Random;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Thread pool task execution completion judgment
*/
public class ThreadPoolCompleted {
public static void main(String[] args) {
// 1. Creating a thread pool
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 20,
0, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1024));
// 2. Add tasks
addTask(threadPool);
// 3. Judge whether the thread pool has been executed
isCompleted(threadPool); // 【 Core call method 】
// 4. Thread pool finished executing
System.out.println();
System.out.println(" Thread pool task execution completed !");
}
/**
* Method 1:isTerminated Realization way
* Judge whether all tasks of the thread pool have been executed
*/
private static void isCompleted(ThreadPoolExecutor threadPool) {
threadPool.shutdown();
while (!threadPool.isTerminated()) { // If it is not finished, it will continue to loop
}
}
/**
* Add tasks to the thread pool
*/
private static void addTask(ThreadPoolExecutor threadPool) {
// Total tasks
final int taskCount = 5;
// Add tasks
for (int i = 0; i < taskCount; i++) {
final int finalI = i;
threadPool.submit(new Runnable() {
@Override
public void run() {
try {
// Random sleep 0-4s
int sleepTime = new Random().nextInt(5);
TimeUnit.SECONDS.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format(" Mission %d Execution completed ", finalI));
}
});
}
}
}
Method statement :shutdown The method is to start the orderly shutdown of the thread pool , It will complete all the submitted tasks before it is completely closed , And will not accept any new tasks . When all the tasks in the thread pool have been executed , The thread pool enters the termination state , call isTerminated Method returns the result that true 了 .
The results of the above procedures are as follows :
Defect analysis :
Need to close thread pool .
Expand : All States of the thread pool
The thread pool contains the following 5 States :
RUNNING: Running state .
SHUTDOWN: The closed position .
STOP: Blocking state .
TIDYING: Sorting status .
TERMINATED: Termination status .
If you don't call the thread pool shutdown method , Then the thread pool will always be in RUNNING Running state .
Method 2:getCompletedTaskCount
We can judge the number of planned tasks and completed tasks in the thread pool , To determine whether the thread pool has been fully executed , If the number of tasks planned to be executed = Number of tasks completed , Then all the tasks of the thread pool will be executed , Otherwise, it will not be completed , The specific implementation code is as follows :
/**
* Method 2:getCompletedTaskCount Realization way
* Judge whether all tasks of the thread pool have been executed
*/
private static void isCompletedByTaskCount(ThreadPoolExecutor threadPool) {
while (threadPool.getTaskCount() != threadPool.getCompletedTaskCount()) {
}
}
The results of the above procedures are as follows :
Method statement
getTaskCount(): Returns the total number of scheduled tasks . Because the state of tasks and threads may change dynamically during the calculation process , So the value returned is just an approximation .
getCompletedTaskCount(): Returns the total number of tasks completed . Because the state of tasks and threads may change dynamically during calculation , So the returned value is only an approximation , But it doesn't decrease in successive calls .
Analysis of advantages and disadvantages
The advantage of this implementation is that there is no need to close the thread pool . Its disadvantages are getTaskCount() and getCompletedTaskCount() What is returned is an approximate value , Because the tasks in the thread pool and the state of threads may change dynamically during the calculation process , So both of them return an approximate value .
Method 3:CountDownLatch
CountDownLatch It can be understood as a counter , We created an include N Counters for tasks , Counter after each task is executed -1, Until the counter goes down to 0 when , It means that all tasks have been performed , Then you can execute the code of the next business , Its implementation process and specific implementation code are as follows :
public static void main(String[] args) throws InterruptedException {
// Creating a thread pool
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 20,
0, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1024));
final int taskCount = 5; // Total tasks
// Single counter
CountDownLatch countDownLatch = new CountDownLatch(taskCount); // ①
// Add tasks
for (int i = 0; i < taskCount; i++) {
final int finalI = i;
threadPool.submit(new Runnable() {
@Override
public void run() {
try {
// Random sleep 0-4s
int sleepTime = new Random().nextInt(5);
TimeUnit.SECONDS.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format(" Mission %d Execution completed ", finalI));
// The thread is finished , Counter -1
countDownLatch.countDown(); // ②
}
});
}
// Blocking waits for the thread pool task to finish executing
countDownLatch.await(); // ③
// Thread pool finished executing
System.out.println();
System.out.println(" Thread pool task execution completed !");
}
Code instructions : The above code is marked as ①、②、③ The line of code is the core implementation code , among : ① Is a declaration that contains 5 Counters for tasks ; ② Is the counter after each task is executed -1; ③ Is the blocking wait counter CountDownLatch Reduced to 0, Indicates that the tasks have been completed , It can be executed await The business code behind the method .
The results of the above procedures are as follows :
Analysis of advantages and disadvantages
CountDownLatch The writing is elegant , And there is no need to close the thread pool , But its disadvantage is that it can only be used once ,CountDownLatch Cannot be reused after being created , in other words CountDownLatch It can be understood as a counter that can only be used once .
Method 4:CyclicBarrier
CyclicBarrier and CountDownLatch similar , It can be understood as a reusable loop counter ,CyclicBarrier You can call reset Method resets itself to the initial state ,CyclicBarrier The specific implementation code is as follows :
public static void main(String[] args) throws InterruptedException {
// Creating a thread pool
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 20,
0, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1024));
final int taskCount = 5; // Total tasks
// Cycle counter ①
CyclicBarrier cyclicBarrier = new CyclicBarrier(taskCount, new Runnable() {
@Override
public void run() {
// Thread pool finished executing
System.out.println();
System.out.println(" All tasks of thread pool have been executed !");
}
});
// Add tasks
for (int i = 0; i < taskCount; i++) {
final int finalI = i;
threadPool.submit(new Runnable() {
@Override
public void run() {
try {
// Random sleep 0-4s
int sleepTime = new Random().nextInt(5);
TimeUnit.SECONDS.sleep(sleepTime);
System.out.println(String.format(" Mission %d Execution completed ", finalI));
// The thread is finished
cyclicBarrier.await(); // ②
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
});
}
}
The results of the above procedures are as follows :
Method statement
CyclicBarrier Yes 3 An important way :
Construction method : The constructor can pass two parameters , Parameters 1 Is the number of counters parties, Parameters 2 Yes, the counter is 0 when , That is, the event that can be executed after all tasks are executed ( Method ).
await Method : stay CyclicBarrier Blocking and waiting on , When this method is called CyclicBarrier Your internal counter will -1, Until one of the following happens :
stay CyclicBarrier The number of threads waiting on the parties, That is, the declared number of counters , All threads are released , Carry on .
The current thread is interrupted , Throw out InterruptedException abnormal , And stop waiting , Carry on .
Other waiting threads are interrupted , The current thread throws BrokenBarrierException abnormal , And stop waiting , Carry on .
Other waiting threads time out , The current thread throws BrokenBarrierException abnormal , And stop waiting , Carry on .
Other thread calls CyclicBarrier.reset() Method , The current thread throws BrokenBarrierException abnormal , And stop waiting , Carry on .
reset Method : bring CyclicBarrier Return to the initial state , Intuitively, it does two things :
If there are waiting threads , It will be thrown out. BrokenBarrierException abnormal , And these threads stop waiting , Carry on .
Will the mark be damaged or not broken Set as false.
Analysis of advantages and disadvantages
CyclicBarrier The complexity from design to use is higher than CountDownLatch, Compared with CountDownLatch Its advantage is that it can be reused ( Just call reset You can return to your original state ), The disadvantage is that it is difficult to use .
summary
We provide 4 A method to judge whether thread pool tasks have been executed :
1、 Use isTerminated Methods to judge : By judging the completion status of the thread pool , Need to close thread pool , Generally not recommended .
2、 Use getCompletedTaskCount Methods to judge : The total number of tasks executed and completed through the plan , To determine whether the tasks of the thread pool have been fully executed , If they are equal, it is determined that all execution is completed . But because thread individuals and states change , So what you get is a rough value , May not be accurate .
3、 Use CountDownLatch Judge : Equivalent to a thread safe single counter , It's easy to use , And there is no need to close the thread pool , It is a common judgment method .
4、 Use CyclicBarrier Judge : Equivalent to a thread safe repeat counter , But the use is more complex , Therefore, it is less used in daily projects .
边栏推荐
- The Alipay in place function can't be found, and the Alipay in place function is offline
- Jupiter notebook shortcut key
- Evolution of Baidu intelligent applet patrol scheduling scheme
- ConstraintLayout官方提供圆角ImageFilterView
- @SerializedName注解使用
- Swift uses userdefaults and codable to save an array of class objects or structure instances
- StaticLayout的使用详解
- 善用兵者,藏于无形,90 分钟深度讲解最佳推广价值作品
- ArcGIS Pro 创建要素
- 横向滚动的RecycleView一屏显示五个半,低于五个平均分布
猜你喜欢
Wechat applet - simple diet recommendation (2)
How to correctly evaluate video image quality
Evolution of Baidu intelligent applet patrol scheduling scheme
Wechat applet - simple diet recommendation (3)
程序员如何活成自己喜欢的模样?
uniapp + uniCloud+unipay 实现微信小程序支付功能
Unity粒子特效系列-毒液喷射预制体做好了,unitypackage包直接用 -下
MySQL character type learning notes
Common fault analysis and Countermeasures of using MySQL in go language
Baidu app's continuous integration practice based on pipeline as code
随机推荐
Uni app running to wechat development tool cannot Preview
Evolution of Baidu intelligent applet patrol scheduling scheme
Energy momentum: how to achieve carbon neutralization in the power industry?
Implementation of smart home project
基于单片机步进电机控制器设计(正转反转指示灯挡位)
CSDN always jumps to other positions when editing articles_ CSDN sends articles without moving the mouse
Constraintlayout officially provides rounded imagefilterview
leetcode:1200. 最小绝对差
让AI替企业做复杂决策真的靠谱吗?参与直播,斯坦福博士来分享他的选择|量子位·视点...
A high density 256 channel electrode cap for dry EEG
善用兵者,藏于无形,90 分钟深度讲解最佳推广价值作品
ArcGIS Pro creating features
天龙八部TLBB系列 - 单体技能群伤
美图炒币半年亏了3个亿,华为被曝在俄罗斯扩招,AlphaGo的同类又刷爆一种棋,今日更多大新闻在此...
RMS TO EAP通过MQTT简单实现
Fluent development: setting method of left and right alignment of child controls in row
能源势动:电力行业的碳中和该如何实现?
Coordinate system of view
宝塔面板MySQL无法启动
程序员如何活成自己喜欢的模样?