Start sharpening to multithreading. This issue is a small example of CountDownLatch.
Definition: CountDownLatch allows one or more threads to wait for other threads to complete operations.
Example of application requirements: suppose there are four threads, A, B, C and D. thread D needs to be executed after A, B and C are executed.
Application requirements analysis: as described above, if you want thread D to execute finally, combined with the previous learning, we can use the join() method. For example, when thread A calls B.join(), thread B calls C.join(), etc., let's recall the join() method: when A thread calls the join() method of another thread, the current thread blocks and waits for the thread called the join() method to execute, This ensures the execution order of threads.
The following is the implementation of the join() method:
public class Demo {
public static void main(String[] args) {
Thread A = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("A");
}
});
Thread B = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("B Start waiting A");
try {
A.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B");
}
});
Thread C = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("C Start waiting B");
try {
B.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("C");
}
});
Thread D = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("D Start waiting C");
try {
C.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("D");
}
});
B.start();
A.start();
C.start();
D.start();
}
}
The results are as follows:
B Start waiting A
C Start waiting B
A
D Start waiting C
B
C
D
Obviously, the join() method can fulfill the final execution requirements of D thread, but it has lost the significance of multi-threaded parallel execution. How to say?
Because threads A, B and C cannot complete synchronous operation, they are still serial in nature. The internal implementation of the join() method is based on the waiting notification mechanism.
To solve this problem, we can use CountdownLatch to realize this kind of communication mode. The usage is as follows:
- The CountdownLatch constructor receives an int type parameter as a counter. If you want to wait for N points, pass in N
- When the countDown() method of CountdownLatch is called, the counter N is decremented by 1
- When await() method is called in the waiting thread, it will enter the waiting state until the counter N becomes 0;
CountdownLatch mode:
public class C {
public static void main(String[] args) {
int N = 3;
CountDownLatch countDownLatch = new CountDownLatch(N);
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("D Waiting for execution...");
try {
countDownLatch.await();
System.out.println("D Start execution");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
for (char threadName='A'; threadName <= 'C'; threadName++) {
final String tN = String.valueOf(threadName);
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(tN + " Executing");
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(tN + " completion of enforcement");
countDownLatch.countDown();
}
}).start();
}
}
}
The results are as follows:
D Waiting for execution...
B Executing
A Executing
C Executing
C completion of enforcement
A completion of enforcement
B completion of enforcement
D Start execution
Application scenario simulation: export the user's bill details, calculate and display them according to the three dimensions of month, year and day, put them into three Excel respectively, and finally merge the Excel into a zip compressed file and return it to the user.
public class Demo2 {
public static void main(String[] args) {
try {
//Simulate the following path and modify it according to your own path
String tempDir = "/C/workspace/File/excel";
//Simulated storage file path
String baseFileName = "202009171016";
String zipFileName = tempDir + "/" + baseFileName + ".zip";
int N = 3;
CountDownLatch mDoneSignal = new CountDownLatch(N);
ExecutorService executor = Executors.newFixedThreadPool(N);
//User's excel path
List<String> excelFileNames = new ArrayList<String>();
for (int i = 0; i < 3; i++) {
File file = new File(tempDir + "/" + baseFileName + "_" + i + ".xls");
file.createNewFile();
excelFileNames.add(tempDir + "/" + baseFileName + "_" + i + ".xls");
executor.execute(new MyThread(file, i, mDoneSignal));
}
//Close startup thread
executor.shutdown();
//Wait for the child thread to end before continuing to execute the following code
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
String[] fileNames = excelFileNames.toArray(new String[excelFileNames.size()]);
try {
mDoneSignal.await();//Wait for all worker threads to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("All data processing completed...");
System.out.println("Start packaging data zip...");
}catch (Exception e) {
e.printStackTrace();
}
}
/**
* Analog thread
*/
public static class MyThread implements Runnable{
private final File file;
private final CountDownLatch mDoneSignal;
private final int index;
public MyThread(File file, int index, CountDownLatch mDoneSignal) {
this.index = index;
this.file = file;
this.mDoneSignal = mDoneSignal;
}
@Override
public void run() {
//Threads execute logic and process , workbooks , etc
switch (index){
case 0:
System.out.println("thread A Execution completed:" + LocalTime.now());
break;
case 1:
System.out.println("thread B Execution completed:" + LocalTime.now());
break;
case 2:
System.out.println("thread C Execution completed:" + LocalTime.now());
break;
}
//When the thread completes, the counter is decremented by one
mDoneSignal.countDown();
}
}
}
The results are as follows:
thread C Execution completed: 10:38:01.454
thread B Execution completed: 10:38:01.455
thread A Execution completed: 10:38:01.455
All data processing completed...
Start packaging data zip...
Blog continues to update, pay attention to subscription, and we will grow together in the future.
This article was first published in blog Park: https://www.cnblogs.com/niceyoo/p/13690231.html