Java使用Condition實現(xiàn)精準(zhǔn)喚醒線程詳解
Condition簡要介紹
Condition是一個接口,創(chuàng)建Condition的實例不能直接new,Java為我們提供一個通過Lock類實例來調(diào)用newCondition()的方法來創(chuàng)建。Condition因素出Object監(jiān)視器方法( wait , notify和notifyAll )到不同的對象,以得到具有多個等待集的每個對象,通過將它們與使用任意的組合的效果Lock個實現(xiàn)。 如果Lock替換了synchronized方法和語句的使用,則Condition將替換Object監(jiān)視方法的使用。
條件(也稱為條件隊列或條件變量 )為一個線程提供暫停執(zhí)行(“等待”)的手段,直到另一個線程通知某個狀態(tài)條件現(xiàn)在可能為真。 由于對此共享狀態(tài)信息的訪問發(fā)生在不同的線程中,因此必須對其進(jìn)行保護(hù),因此某種形式的鎖定與該條件相關(guān)聯(lián)。 等待條件提供的關(guān)鍵屬性是它以原子方式釋放關(guān)聯(lián)的鎖并掛起當(dāng)前線程,就像Object.wait一樣。
Condition里的主要方法

使用Condition的Demo
例子1
package testJUC;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestCondition {
public static void main(String[] args) {
Product3 product = new Product3();
new Thread(()->{
for (int i = 0; i < 5; i++)
new Producer(product).getProduct();
},"工廠").start();
new Thread(()->{
for (int i = 0; i < 5; i++)
new Consumer(product).saleProduct();
},"學(xué)生").start();
}
}
class Product3 {
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private int flag = 1;//標(biāo)識符
public void getProduct() {
//加鎖
lock.lock();
try {
//使用while循環(huán),可以有效避免線程虛假喚醒
while (flag != 1) {
condition1.await();
}
flag = 2;
//喚醒saleProduct
condition2.signal();
System.out.println(Thread.currentThread().getName() + "生產(chǎn)一個產(chǎn)品");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//解鎖
lock.unlock();
}
}
public void saleProduct() {
lock.lock();
try {
while (flag != 2) {
condition2.await();
}
flag = 1;
//喚醒getProduct
condition1.signal();
System.out.println(Thread.currentThread().getName()+"消費了一個產(chǎn)品");
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
//實體類
class Producer{
private Product3 product = null;
public Producer(Product3 product) {
this.product = product;
}
public void getProduct(){
product.getProduct();
}
}
class Consumer{
private Product3 product = null;
public Consumer(Product3 product) {
this.product = product;
}
public void saleProduct(){
product.saleProduct();
}
}
結(jié)果

例子2
package testJUC;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestCondition {
public static void main(String[] args) {
Print print = new Print();
new Thread(() -> {
for (int i = 0; i < 5; i++)
print.printA();
}).start();
new Thread(() -> {
for (int i = 0; i < 5; i++)
print.printB();
}).start();
new Thread(() -> {
for (int i = 0; i < 5; i++)
print.printC();
}).start();
}
}
class Print {
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
private int number = 1;
//輸出A的方法
public void printA() {
//加鎖
lock.lock();
try {
//使用while循環(huán),可以有效避免線程虛假喚醒
while (number != 1) {
condition1.await();
}
number = 2;
//喚醒輸出B的方法
condition2.signal();
System.out.println("AAA");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//解鎖
lock.unlock();
}
}
//輸出B的方法
public void printB() {
//加鎖
lock.lock();
try {
while (number != 2) {
condition2.await();
}
System.out.println("BBB");
number = 3;
//喚醒C
condition3.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//喚醒輸出C的方法
lock.unlock();
}
}
//輸出C的方法
public void printC() {
//加鎖
lock.lock();
try {
while (number != 3) {
condition3.await();
}
System.out.println("CCC");
number = 1;
//喚醒輸出A的方法
condition1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//解鎖
lock.unlock();
}
}
}結(jié)果2

到此這篇關(guān)于Java使用Condition實現(xiàn)精準(zhǔn)喚醒線程詳解的文章就介紹到這了,更多相關(guān)Java Condition精準(zhǔn)喚醒線程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java中double強(qiáng)制轉(zhuǎn)換int引發(fā)的OOM問題記錄
這篇文章主要介紹了java中double強(qiáng)制轉(zhuǎn)換int引發(fā)的OOM問題記錄,本文給大家分享問題排查過程,感興趣的朋友跟隨小編一起看看吧2024-10-10
java隨機(jī)生成8位數(shù)授權(quán)碼的實例
下面小編就為大家?guī)硪黄猨ava隨機(jī)生成8位數(shù)授權(quán)碼的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02
SpringBoot+WebSocket實現(xiàn)即時通訊功能(Spring方式)
今天給大家分享一個SpringBoot+WebSocket實現(xiàn)即時通訊功能(Spring方式),WebSocket是一種在單個TCP連接上進(jìn)行全雙工通信的協(xié)議,文章通過代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10
SpringBoot 枚舉類型的自動轉(zhuǎn)換的實現(xiàn)
一般我們在數(shù)據(jù)庫都會定義數(shù)值型的枚舉常量,不管是序列化還是反序列化都是需要我們手動去轉(zhuǎn)換成枚舉類型的,本文主要介紹了Spring Boot 枚舉類型的自動轉(zhuǎn)換,感興趣的可以了解一下2022-03-03

