Lock物件Condition介面實現等待/通知
關鍵字Synchronized與wait()和notify()/notifyAll()方法相結合可以實現等待通知,ReentrantLock藉助Condition物件可以實現同樣的功能,而且一個lock物件可以建立多個condition物件,從而能夠選擇性condition物件進行等待/通知
condition物件實現等待通知的簡單案例
public class ConditionLockDemo {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void csleep(){
try{
lock.lock();
System.out.println(Thread.currentThread().getName()+"current time :"+System.currentTimeMillis());
condition.await();
System.out.println(Thread.currentThread().getName()+"喚醒後 current time :"+System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
public void signal(){
try{
lock.lock();
condition.signal();
}finally{
lock.unlock();
}
}
}
啟動兩個執行緒,分別呼叫兩個方法
public static void main(String[] args) throws InterruptedException {
final ConditionLockDemo cl = new ConditionLockDemo();
Thread a = new Thread(new Runnable() {
@Override
public void run() {
cl.csleep();
}
}, "A");
Thread b = new Thread(new Runnable() {
@Override
public void run() {
cl.signal();
}
}, "B");
a.start();
Thread.sleep(1000);
b.start();
}
輸出:
Acurrent time :1525329885799
A喚醒後 current time :1525329886799
從這個簡單案例:
* condition 物件是lock物件進行建立的,而且一個lock物件可以建立多個condition物件
* 等待通知的實現,藉助condition 物件的await()方法進入阻塞狀態釋放鎖,signal方法喚醒waiting的執行緒
* await()和signal方法的呼叫必須都要先在獲取到鎖之後(lock.lock())
方法 | 描述 |
await() | 當前執行緒進入waiting狀態,並且釋放當前執行緒的鎖,當前執行緒被喚醒,直到其他執行緒呼叫signal、signalAll或者interrupt方法 如果執行緒從await方法返回,表示已經獲取到鎖 |
awaitUninterruptibly() | 和上面方法一致,區別在於對於其他執行緒的中斷方法不敏感 |
awaitUntil(Date deadline) | 當前執行緒進入等待狀態直到被通知、中斷或者到某個時間點,如果沒有到時間點就被通知,方法返回true,否則到了指定時間,返回false |
signal() | 獲取到鎖後,喚醒處於waiting狀態的執行緒 |
signalAll() | 獲取到鎖後,喚醒所有處在waiting狀態的執行緒 |
condition實現生產者消費者模型
3個執行緒輪流列印1,2,3 。。。
思想:
3個執行緒,建立3個condition物件
3個執行緒讀取同一個共享變數的值,然後根據值,判斷是否進入阻塞狀態
,如果不是阻塞狀態,修改這個值,並喚醒下一個執行緒, A-B-C-A輪流喚醒
public class ThreeConditionDemo {
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
private volatile int count = 1;
public void printA() {
try{
lock.lock();
while(count!=1){
condition1.await();
}
Thread.sleep(1000);
System.out.println("1");
count = 2 ;
condition2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
public void printB(){
try{
lock.lock();
while(count!=2){
condition2.await();
}
Thread.sleep(1000);
System.out.println("2");
count = 3;
condition3.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
public void printC(){
try{
lock.lock();
while(count!=3){
condition3.await();
}
Thread.sleep(1000);
System.out.println("3");
count = 1;
condition1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
}
啟動三個執行緒測試:
public static void main(String[] args) {
final ThreeConditionDemo tcd = new ThreeConditionDemo();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
tcd.printA();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
tcd.printB();
}
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
tcd.printC();
}
}
});
t1.start();
t2.start();
t3.start();
}
Object監視器鎖和Condition方法的對比對比項 | Object監視器方法 | Condition |
前置條件 | 獲取object物件的鎖 | 呼叫lock.lock()獲取鎖 |
呼叫方法 | object.wait/notify,notifyAll | Condition condition = lock.newCondition() condition.await/signal,signalAll |
釋放鎖進入等待狀態,能夠不響應中斷 | 不支援 | 支援 |
釋放鎖進入超時等待 | 支援 | 支援 |
等待佇列的個數 | 1個 | 多個,lock可以建立多個condition,呼叫一個condition.await方法 就加入等待佇列中 |
相關文章
- Lock介面之Condition介面
- 再談AbstractQueuedSynchronizer2:共享模式與基於Condition的等待/通知機制實現模式
- 詳解Condition的await和signal等待/通知機制AI
- C++11中的mutex, lock, condition variable實現分析C++Mutex
- Java併發程式設計,Condition的await和signal等待通知機制Java程式設計AI
- 鎖——Lock、Condition、ReadWriteLock、LockSupport
- Condition實現原理
- 併發王者課-鉑金6:青出於藍-Condition如何把等待與通知玩出新花樣
- 等待事件之Row Cache Lock事件
- LIBRARY CACHE LOCK 等待事件事件
- enable table lock 的enqueue等待ENQ
- latch:library cache lock等待事件事件
- 關於DFS lock handle等待事件事件
- Synchronized、lock、volatile、ThreadLocal、原子性總結、Conditionsynchronizedthread
- 【實驗】【LOCK】“鎖等待”模擬、診斷及處理方法
- Java™ 教程(Lock物件)Java物件
- 等待事件enq: TX - row lock contention事件ENQ
- LightDB/PostgreSQL等待事件 Lock transactionidSQL事件
- 【等待事件】-enq: TX - row lock contention事件ENQ
- enq:Library cache lock/pin等待事件ENQ事件
- [ORACLE 11G]ROW CACHE LOCK 等待Oracle
- Java併發之等待/通知機制Java
- 透徹理解Java併發的等待佇列——ConditionJava佇列
- JAVA 將介面的引用指向實現類的物件Java物件
- java多執行緒與併發 - 自己實現一個簡單的鎖(實現Lock介面)Java執行緒
- Java併發程式設計實戰--顯式的Condition物件Java程式設計物件
- 11.2資料庫登入出現library cache lock等待(二)資料庫
- 11.2資料庫登入出現library cache lock等待(一)資料庫
- 等待事件enq TX row lock contention分析事件ENQ
- MySQL 5.5 -- innodb_lock_wait 鎖 等待MySqlAI
- 多執行緒之等待通知機制執行緒
- C#動態建立介面的實現例項物件C#物件
- 【TUNE_ORACLE】等待事件之“library cache lock”Oracle事件
- MySQL 5.6 drop database時,table metadata lock等待MySqlDatabase
- zt_library cache pin和lock等待分析
- enq: TX - row lock contention等待事件處理ENQ事件
- 尋找 library cache lock 等待事件的session事件Session
- 'library cache lock'等待事件的處理方法事件