It is not difficult to run a program; the difficult thing is how far the program can run! —— a fierce seed
JUC Concurrency Series
1. What is Condition
Condition was updated in jdk1.5, which can be used to replace the original wait and notify to achieve inter-thread cooperation, because Condition's await and signal methods are safer and more efficient.
You can see the previous in-depth multithreading series. We use the monitor method and the semaphore method to solve the problem of producers and consumers by using wait and notify .
In-depth multi-threading 15: the management method to solve the problem of producers and consumers
In-depth multi-threading sixteen: semaphore way to solve the problem of producers and consumers
2. Hand type code to achieve Condition to achieve accurate notification wake
There is a scenario where we want an output result to be executed in the order of ABC, then we use today's protagonist Condition to achieve.
2.1 Condition is not used
Before implementing the Condition to accurately notify the wake-up, first look at the code segment that does not use the Condition to output the result. (Comparing learning is more intuitive)
public class demo{
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 5; i++) {
data.testA();
}
},"一颗剽悍的种子A").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
data.testB();
}
},"一颗剽悍的种子B").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
data.testC();
}
},"一颗剽悍的种子C").start();
}
}
class Data{
public void testA(){
System.out.println(Thread.currentThread().getName() + "A");
}
public void testB(){
System.out.println(Thread.currentThread().getName() + "B");
}
public void testC(){
System.out.println(Thread.currentThread().getName() + "C");
}
}
operation result
You can see that the order is messed up, not in the order of execution we want.
2.2 Use Condition to achieve accurate notification wakeup
Synchronized is an exclusive lock. The process of locking and unlocking is performed automatically, which is easy to operate, but not flexible enough. ReentrantLock is also an exclusive lock, but the process of locking and unlocking needs to be done manually, which is not easy to operate, but very flexible.
Key code
Manual lock -> Judgment -> Execution -> Notification -> Manual lock
public void testA(){
lock.lock();
try {
while (num != 1){
conditionA.await(); //等待
}
System.out.println(Thread.currentThread().getName() + "A");
num++;
conditionB.signal(); //通知
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
All codes
public class demo{
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (Integer i = 0; i < 5; i++) {
data.testA();
}
},"一颗剽悍的种子A").start();
new Thread(()->{
for (Integer i = 0; i < 5; i++) {
data.testB();
}
},"一颗剽悍的种子B").start();
new Thread(()->{
for (Integer i = 0; i < 5; i++) {
data.testC();
}
},"一颗剽悍的种子C").start();
}
}
class Data{
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private Condition conditionC = lock.newCondition();
private Integer num = 1; //1 = A 2 = B 3 = C
public void testA(){
lock.lock();
try {
while (num != 1){
conditionA.await(); //等待
}
System.out.println(Thread.currentThread().getName() + "A");
num++;
conditionB.signal(); //通知
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void testB(){
lock.lock();
try {
while (num != 2){
conditionB.await(); //等待
}
System.out.println(Thread.currentThread().getName() + "B");
num++;
conditionC.signal(); //通知
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void testC(){
lock.lock();
try {
while (num != 3){
conditionC.await(); //等待
}
System.out.println(Thread.currentThread().getName() + "C");
num = 1;
conditionA.signal(); //通知
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
operation result
3. Prevent false wakeups
If you have seen the previous in-depth multithreading series or the code above, if you pay attention, you will find that we use the while judgment more than if in the judgment , because if there may be false wakeups.
So what is to prevent false wakeups?
The so-called false wakeup means that although the thread can wake up, it will not be notified, interrupted or timed out.
Four, finally
At the end, for a better reading experience, I put everything I want to say below, hehe.
I am a seed of decisions based on my will, serious share what I wrote blog has been the same creed.
If you can read this blog post, it means that we are still very destined; I hope it can bring you some help, the creation is not easy, take away the knowledge of my article, your three consecutive leave, like, comment, follow , Is my biggest motivation.