Multithreading concurrency is mainly multithreading operation resource class, followed by multithreading communication, trilogy, judgment, work, and notification. In order to prevent false wake-up judgment, while must be used. Finally, in order to ensure the order of multithreading execution, Condition matching flag bit can be used to notify the designated thread to wake up.
bounded-buffer problem
Two threads operate the air conditioning resource class, one heating degree, one desuperheating degree, one return, 10 cycles
Version 1
Trilogy of communication among multiple threads, judgment, work, notice and wake up other threads
package com.zbiti.juc; //High cohesion and low coupling, multithreaded operation resource class //Multithreaded communication judgment / work / notification to prevent false wake-up judgment public class ProducerConsumerDemo { public static void main(String[] args) { AirConditon airConditon = new AirConditon(); new Thread(()->{ try { for(int i=1;i<=10;i++){ airConditon.increament(); } } catch (Exception e) { e.printStackTrace(); } },"AA").start(); new Thread(()->{ try { for(int i=1;i<=10;i++){ airConditon.decreament(); } } catch (Exception e) { e.printStackTrace(); } },"BB").start(); } } //Air conditioning resources with plus degree and minus degree functions class AirConditon { int number = 0; synchronized void increament() throws Exception { //judge if (number != 0) { this.wait(); } //work number++; System.out.println(Thread.currentThread().getName()+"\t"+number); //notice this.notifyAll(); } synchronized void decreament() throws Exception { //judge if (number != 1) { this.wait(); } //work number--; System.out.println(Thread.currentThread().getName()+"\t"+number); //notice this.notifyAll(); } }
Result
The result is correct at this time
AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 Process finished with exit code 0
If it's four threads, two producers and two consumers
package com.zbiti.juc; //High cohesion and low coupling, multithreaded operation resource class //Multithreaded communication judgment / work / notification to prevent false wake-up judgment public class ProducerConsumerDemo { public static void main(String[] args) { AirConditon airConditon = new AirConditon(); new Thread(()->{ try { for(int i=1;i<=10;i++){ airConditon.increament(); } } catch (Exception e) { e.printStackTrace(); } },"AA").start(); new Thread(()->{ try { for(int i=1;i<=10;i++){ airConditon.decreament(); } } catch (Exception e) { e.printStackTrace(); } },"BB").start(); new Thread(()->{ try { for(int i=1;i<=10;i++){ airConditon.increament(); } } catch (Exception e) { e.printStackTrace(); } },"CC").start(); new Thread(()->{ try { for(int i=1;i<=10;i++){ airConditon.decreament(); } } catch (Exception e) { e.printStackTrace(); } },"DD").start(); } } //Air conditioning resources with plus degree and minus degree functions class AirConditon { int number = 0; synchronized void increament() throws Exception { //judge if (number != 0) { this.wait(); } //work number++; System.out.println(Thread.currentThread().getName()+"\t"+number); //notice this.notifyAll(); } synchronized void decreament() throws Exception { //judge if (number != 1) { this.wait(); } //work number--; System.out.println(Thread.currentThread().getName()+"\t"+number); //notice this.notifyAll(); } }
Result
We can see that the result is not in line with our expectation
AA 1 DD 0 CC 1 AA 2 CC 3 DD 2 CC 3 BB 2 AA 3 BB 2 CC 3 DD 2 CC 3 BB 2 AA 3 BB 2 CC 3 DD 2 CC 3 BB 2 AA 3 BB 2 CC 3 DD 2 CC 3 BB 2 AA 3 BB 2 CC 3 DD 2 BB 1 BB 0 AA 1 DD 0 AA 1 DD 0 AA 1 DD 0 AA 1 DD 0 Process finished with exit code 0
Version two
To prevent false wake-up, use while to judge
Version three
Using ReentrantLock, the difference is that the condition.await(); and condition.signalAll(); of Condition are used for waiting and awaking;
package com.zbiti.juc; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; //High cohesion and low coupling, multithreaded operation resource class //Multithreaded communication judgment / work / notification to prevent false wake-up judgment public class ProducerConsumerDemo { public static void main(String[] args) { AirConditon airConditon = new AirConditon(); new Thread(() -> { try { for (int i = 1; i <= 10; i++) { airConditon.increament(); } } catch (Exception e) { e.printStackTrace(); } }, "AA").start(); new Thread(() -> { try { for (int i = 1; i <= 10; i++) { airConditon.decreament(); } } catch (Exception e) { e.printStackTrace(); } }, "BB").start(); new Thread(() -> { try { for (int i = 1; i <= 10; i++) { airConditon.increament(); } } catch (Exception e) { e.printStackTrace(); } }, "CC").start(); new Thread(() -> { try { for (int i = 1; i <= 10; i++) { airConditon.decreament(); } } catch (Exception e) { e.printStackTrace(); } }, "DD").start(); } } //Air conditioning resources with plus degree and minus degree functions class AirConditon { int number = 0; Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); void increament() throws Exception { lock.lock(); try { //judge while (number != 0) { condition.await(); } //work number++; System.out.println(Thread.currentThread().getName() + "\t" + number); //notice condition.signalAll(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } void decreament() throws Exception { lock.lock(); try { //judge while (number != 1) { condition.await(); } //work number--; System.out.println(Thread.currentThread().getName() + "\t" + number); //notice condition.signalAll(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }
Result
AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 AA 1 BB 0 CC 1 DD 0 CC 1 DD 0 CC 1 DD 0 CC 1 DD 0 CC 1 DD 0 CC 1 DD 0 CC 1 DD 0 CC 1 DD 0 CC 1 DD 0 CC 1 DD 0 Process finished with exit code 0
Condition notification wakes up a specific thread
Principle of multithreading communication, judgment, work and notification
Use Condition to cooperate with flag bit to inform specific thread to work, and modify flag bit before notification
package com.zbiti.juc; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; //Three threads a B C, a print 5 times, B print 10 times, C print 15 times, cycle 10 times public class ConditionDemo { public static void main(String[] args) { ShareData shareData = new ShareData(); new Thread(() -> { for (int i = 1; i <= 10; i++) { shareData.print5(); } }, "A").start(); new Thread(() -> { for (int i = 1; i <= 10; i++) { shareData.print10(); } }, "B").start(); new Thread(() -> { for (int i = 1; i <= 10; i++) { shareData.print15(); } }, "C").start(); } } //Resource class class ShareData { Lock lock = new ReentrantLock(); Condition c1 = lock.newCondition(); Condition c2 = lock.newCondition(); Condition c3 = lock.newCondition(); //Flag bit 1 thread A execution, 2 thread B execution, 3 thread C execution int number = 1; void print5() { lock.lock(); try { //judge while (number != 1) { c1.await(); } //work for (int i = 1; i <= 5; i++) { System.out.println(Thread.currentThread().getName() + "\t" + i); } //Change flag before notification number = 2; c2.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } void print10() { lock.lock(); try { //judge while (number != 2) { c2.await(); } //work for (int i = 1; i <= 10; i++) { System.out.println(Thread.currentThread().getName() + "\t" + i); } //notice number = 3; c3.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } void print15() { lock.lock(); try { //judge while (number != 3) { c3.await(); } //work for (int i = 1; i <= 15; i++) { System.out.println(Thread.currentThread().getName() + "\t" + i); } //notice number = 1; c1.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }
Small summary
Trilogy of inter thread communication, judgment, work, and notification wake-up. In order to prevent false wake-up, while is used for judgment
synchronized version
ReentrantLock version
Condition notifies to wake up a specific thread, and modifies the flag bit before the notification wakes up
This article is based on the platform of blog one article multiple sending OpenWrite Release!