5. CountDownLatch
In many documents, CountDownLatch is a countdown counter. I think this is too professional. In fact, it is actually a counting person. With this function, you can complete the multi-thread wait after the multi-thread execution task is completed, so that you can wait for all the threads to do other things. This is a bit similar to FutureTask, which is not used in the same way. In this scenario, a thread can be executed only after the execution of other threads is completed. Note that this thread does not need the execution results of other threads, however, only one condition is that other threads must complete the execution. Let's still make a metaphor. Wei xiaobao needs eight articles titled chapter 42 to go to luding Hill to find the treasure. What should I do? He has seven wives and cannot waste resources? Let's do this task at the same time. Let's design 8 threads at the same time. When all our wives have completed the execution, every wife has gone through chapter forty-two classics. Now, he can find his own treasure. Wait, we have seven wives. Why are there eight threads? The readers don't have to be honest about this problem. Let's just give him a wife!
The Code is as follows:
Java code
<Span style = "font-size: small;"> package threadConcurrent. test;
Import java. util. concurrent. CountDownLatch;
/**
* Execute tasks by branch
*
* @ Author liuyan
*
*/
Public class CountDownLatchDemo implements Runnable {
Private int id;
// There is no impact between threads. Continue to do your own thing after the end.
Private CountDownLatch countDownLatch;
Public CountDownLatchDemo (int id, CountDownLatch countDownLatch ){
This. id = id;
This. countDownLatch = countDownLatch;
}
@ SuppressWarnings ("static-access ")
@ Override
Public void run (){
Try {
System. out. println ("the" + (id + 1) + "The wife began to search for Chapter 42 of the classics...");
Thread. currentThread (). sleep (id * 1000 );
System. out. println ("no." + (id + 1) + "found in Chapter 42 of this Article ");
// The counter will wait for the number-1
CountDownLatch. countDown ();
System. out. println ("Number" + (id + 1) + "wife continues to do other things ");
} Catch (InterruptedException e ){
E. printStackTrace ();
}
}
Public static void main (String [] args ){
CountDownLatch countDownLatch = new CountDownLatch (8 );
For (int I = 0; I <8; I ++ ){
New Thread (new CountDownLatchDemo (I, countDownLatch). start ();
}
Try {
System. out. println ("Wei xiaobao is waiting for 8 Chapter 42 ...... ");
// Wei xiaobao is waiting
CountDownLatch. await ();
// Wait for the athlete to reach the end
System. out. println ("8 this forty-two chapter has been searched for, you can find the treasure! ");
} Catch (InterruptedException e ){
E. printStackTrace ();
}
}
} </Span>
The main thread is regarded as Wei xiaobao. The main thread first opened up the thread counter object, and then opened up eight threads, sent eight wives to handle the affairs, and then the main thread called countDownLatch. await () blocking, drinking tea at home, listening to Xiaoqu waiting for the completion of 8 threads. Let's take a look at our wives. The wives worked hard and began to look for the Scriptures. Then they called countDownLatch. countDown () to notify the thread counter to subtract 1 and let the waiting thread subtract 1. For example, if a wife finds Chapter 42 Sutra and sends a multimedia message to Wei xiaobao using the iphone, Wei xiaobao receives it. Well, this wife is competent and the task is completed, my waiting target minus 1. When the waiting thread is 0, xiaobao starts to take action, and passes the map in the mobile phone through the game-jigsaw puzzle game. After a piece of work, a major event can be achieved, and you can find your own treasure! Here we also see the difference between CountDownLatch and FutureTask. CountDownLatch focuses on the number of completed sub-threads. Each time a sub-thread is completed, the number of waiting threads is reduced by one. When the thread is 0, the main thread will not be blocked and start to go down. However, once the sub-thread calls countDownLatch. the countDown () method means that the thread-based tasks are handled. The main thread won't be unable to go down because of your other tasks. As a result, the wives can also travel and take a rest! FutureTask focuses on the execution results, and the main thread needs the exact results. Therefore, the call () executed by futureTask has a return value.
6. CyclicBarrier
The biggest difference between CyclicBarrier and CountDownLatch is that the specific execution process of sub-threads is affected by other sub-threads. Each sub-thread must be executed completely before the main thread continues to go down, if there are other actions after all the sub-threads are executed, OK, you are free and don't have to block it. Let's go down your path. This example is an example of online game players. If there are four children playing the game, the game requires that four children have to go through the first level to enable the second level! Otherwise, other people who have completed the first level will have to wait for others to complete. This is a bit like our project development, module development, module aggregation, joint debugging, and testing at a certain stage. If one module is not completed at this time, please wait, everyone is quietly there, staring at you, waiting for you.
Java code
<Span style = "font-size: small;"> package threadConcurrent. test;
Import java. util. concurrent. BrokenBarrierException;
Import java. util. concurrent. javasicbarrier;
Public class GameBarrier {
Public static void main (String [] args ){
CyclicBarrier extends icbarrier = new cyclicBarrier (4, new Runnable (){
@ Override
Public void run (){
System. out. println ("all players enter Level 2! ");
}
});
For (int I = 0; I <4; I ++ ){
New Thread (new Player (I, cyclicBarrier). start ();
}
}
}
Class Player implements Runnable {
/**
* Interaction is required between threads. Under certain conditions, all threads can go down.
*/
Private CyclicBarrier extends icbarrier;
Private int id;
Public Player (int id, CyclicBarrier extends icbarrier ){
This. Required icbarrier = required icbarrier;
This. id = id;
}
@ Override
Public void run (){
Try {
System. out. println ("Player" + id + "playing first level ...");
CyclicBarrier. await ();
System. out. println ("Player" + id + "enters Level 2 ...");
} Catch (InterruptedException e ){
E. printStackTrace ();
} Catch (BrokenBarrierException e ){
E. printStackTrace ();
}
}
} </Span>
Use javasicbarrier. await (); the method is waiting and congested. When all the sub-threads are finished, the main thread starts to execute, and the sub-thread freedom is freed. Continue and start the second level.
7. Exchanger
Exchanger is A thread resource switch. In A running stage, thread A and thread B need to swap resources to complete the task. This is like Ye xiaochai, a company employee, and a book. In different project groups-group A and group B, two groups of developers have different projects. Normally, ye xiaochai works for the developer BOSS project in group, one page is used to develop the ESB middleware product in Project B. In special periods, Project Team B does not need A single page of books. If ye xiaochai needs to provide technical support, he and project team A need ye xiaochai. The leader of Project Team A is not vegetarian. You need ye xiaochai, no problem. You have to take a page of books to our project team for a few days! In this way, Project Team B and Project Team A have made such A "transaction" (exchange ~ Check the program.
Java code
<Span style = "font-size: small;"> package threadConcurrent. test;
Import java. util. concurrent. Exchanger;
/**
* Resource Exchange
* @ Author liuyan
*/
Public class ExgrDemo {
Public static void main (String args []) {
// Switch
Exchanger <String> exgr = new Exchanger <String> ();
New TeamB (exgr );
New TeamA (exgr );
}
}
/**
* Project Team
* @ Author liuyan
*/
Class TeamA implements Runnable {
Exchanger <String> ex;
String str;
TeamA (Exchanger <String> c ){
Ex = c;
Str = new String ();
New Thread (this). start ();
}
Public void run (){
Char ch = 'a ';
For (int I = 0; I <3; I ++ ){
For (int j = 0; j <5; j ++)
Str + = (char) ch ++;
Try {
Str = ex. exchange (str );
} Catch (InterruptedException exc ){
System. out. println (exc );
}
}
}
}
/**
* Project Team B
* @ Author liuyan
*/
Class TeamB implements Runnable {
Exchanger <String> ex;
String str;
TeamB (Exchanger <String> c ){
Ex = c;
New Thread (this). start ();
}
Public void run (){
For (int I = 0; I <3; I ++ ){
Try {
Str = ex. exchange (new String ());
System. out. println ("Got:" + str );
} Catch (InterruptedException exc ){
System. out. println (exc );
}
}
}
}
</Span>
It should be noted that this kind of switching must be paired, that is, the number of switching threads must be an even number. Otherwise, there will be an odd number of threads, and the other one will exchange with whom? This is also an embodiment of "equivalent transaction.
8. Summary
This article mainly introduces the concurrent packet sending that is often used in a concurrent environment to control concurrent scheduling, synchronization, interaction, exchange, and collaboration of multiple threads. By using these cooperative syntaxes, You can process the relationships between threads more flexibly. It can also make better use of hardware resources to provide efficient operation capabilities for our concurrent systems. Of course, this summary is only limited to the use level, and the underlying implementation source code analysis has time to make a summary.