生產者和消費者問題
阿新 • • 發佈:2021-02-14
技術標籤:# JUC
-
synchronized演示生產者和消費者問題
// 執行緒也可以喚醒,而不會接通知,終端或者超時,即所謂的虛假喚醒,等待應該總是出現在迴圈中,while取代if public class TraditionalProConsumer { public static void main(String[] args) { // 建立資源物件 Num num = new Num(); // 開啟執行緒 new Thread(() -> { for (int i = 0; i <
-
通過Lock 找到 Condition演示生產者和消費者問題
public class LockProConsumer { public static void main(String[] args) { // 建立資源物件 Data num = new Data(); // 開啟執行緒 new Thread(() -> { for (int i = 0; i < 10; i++) { num.decrement(); } }, "A").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { num.increment(); } }, "B").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { num.increment(); } }, "C").start(); new Thread(() -> { for (int i = 0; i < 10; i++) { num.decrement(); } }, "D").start(); } } // 資源類 class Data { private int num = 0; // Lock方式 // 1. 建立一個鎖 Lock lock = new ReentrantLock(); // 2. 繫結condition Condition condition = lock.newCondition(); // +1 public void increment() { // 1. 加鎖 lock.lock(); // 2. 業務邏輯 try { while (num != 0) { // 1>. 等待 condition.await(); } // 2>. 業務邏輯 num++; System.out.println(Thread.currentThread().getName() + "->" + num); // 3>. 喚醒 condition.signalAll(); } catch (Exception e) { e.printStackTrace(); } finally { // 3. 解鎖 lock.unlock(); } } // -1 public void decrement() { // 1. 加鎖 lock.lock(); // 2. 業務邏輯 try { while (num == 0) { // 1>. 等待 condition.await(); } // 2>. 業務邏輯 num--; System.out.println(Thread.currentThread().getName() + "->" + num); // 3>. 喚醒 condition.signalAll(); } catch (Exception e) { e.printStackTrace(); } finally { // 3. 解鎖 lock.unlock(); } } }
-
通過Lock 找到 Condition精準通知和喚醒 執行緒
public class LockSeqABCD {
public static void main(String[] args) {
Data1 data1 = new Data1();
// 開啟執行緒
new Thread(() -> {
for (int i = 0; i < 10; i++) {
data1.printA();
}
}, "A").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
data1.printB();
}
}, "B").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
data1.printC();
}
}, "C").start();
}
}
// 資源類
class Data1 {
// 鎖
private Lock lock = new ReentrantLock();
// 三個監視器
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
// 資料
private int num = 1;
// 三個方法
public void printA() {
// 1. 加鎖
lock.lock();
// 2. 業務邏輯
try {
while (num != 1) {
// 1>. 判斷等待
condition1.await();
}
// 2>. 業務邏輯
num = 2;
System.out.println(Thread.currentThread().getName() + "->AAA");
// 3>. 喚醒,指定喚醒,用指定的監視器
condition2.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 3. 解鎖
lock.unlock();
}
}
public void printB() {
// 1. 加鎖
lock.lock();
// 2. 業務邏輯
try {
while (num != 2) {
// 1>. 判斷等待
condition2.await();
}
// 2>. 業務邏輯
num = 3;
System.out.println(Thread.currentThread().getName() + "->AAA");
// 3>. 喚醒,指定喚醒,用指定的監視器
condition3.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 3. 解鎖
lock.unlock();
}
}
public void printC() {
// 1. 加鎖
lock.lock();
// 2. 業務邏輯
try {
while (num != 3) {
// 1>. 判斷等待
condition3.await();
}
// 2>. 業務邏輯
num = 1;
System.out.println(Thread.currentThread().getName() + "->AAA");
// 3>. 喚醒,指定喚醒,用指定的監視器
condition1.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 3. 解鎖
lock.unlock();
}
}
}