參考:https://segmentfault.com/a/1190000014419022?utm_source=index-hottest#item-1-2
synchronized關鍵字與wait()和notify/notifyAll()方法相結合可以實現等待/通知機制,ReentrantLock類當然也可以實現,但是需要藉助於Condition接口與newCondition() 方法
一個Lock對象中可以創建多個Condition實例(即對象監視器),線程對象可以註冊在指定的Condition中,從而可以有選擇性的進行線程通知,在調度線程上更加靈活,在使用notify/notifyAll()方法進行通知時,被通知的線程是有JVM選擇的,使用ReentrantLock類結合Condition實例可以實現“選擇性通知”,這個功能非常重要,而且是Condition接口默認提供的。
而synchronized關鍵字就相當於整個Lock對象中只有一個Condition實例,所有的線程都註冊在它一個身上。如果執行notifyAll()方法的話就會通知所有處於等待狀態的線程這樣會造成很大的效率問題,而Condition實例的signalAll()方法 只會喚醒註冊在該Condition實例中的所有等待線程
package com.xq.demo.condition;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class UseSingleConditionWaitNotify {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
ThreadA a = new ThreadA(service);
a.start();
Thread.sleep(3000);
service.signal();
}
static public class MyService {
private Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
public void await() {
lock.lock();
try {
System.out.println(" await時間爲" + System.currentTimeMillis());
condition.await();
System.out.println("這是condition.await()方法之後的語句,condition.signal()方法之後我才被執行");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void signal() throws InterruptedException {
lock.lock();
try {
System.out.println("signal時間爲" + System.currentTimeMillis());
condition.signal();
Thread.sleep(3000);
System.out.println("這是condition.signal()方法之後的語句");
} finally {
lock.unlock();
}
}
}
static public class ThreadA extends Thread {
private MyService service;
public ThreadA(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.await();
}
}
}