Condition是一個多執行緒間協調通訊的工具類,使得某個,或者某些執行緒一起等待某個條件(Condition),只有當該條件具備( signal 或者 signalAll方法被帶呼叫)時 ,這些等待執行緒才會被喚醒,從而重新爭奪鎖。
Condition例項實質上被繫結到一個鎖上。一個鎖內部可以有多個Condition,即有多路等待和通知。要為特定 Lock 例項獲得 Condition 例項,請使用其 newCondition() 方法。
Condition newCondition() 返回用來與當前Lock例項一起使用的Condition 例項。
類似於 object.wait()和object.notify()的功能。object.wait()與object.notify()需要結合synchronized使用。Condition需要結合ReentrantLock使用。
四種方法:
await()方法會使當前執行緒等待,同時釋放當前鎖,當其他執行緒中使用signal()時或者signalAll()方法時,執行緒會重新獲得鎖並繼續執行。或者當執行緒被中斷時,也能跳出等待。這和Object.wait()方法很相似。
awaitUninterruptibly()方法與await()方法基本相同,但awaitUninterruptibly()方法不會在等待過程中響應中斷。
singal()方法用於喚醒一個在等待中的執行緒。相對的singalAll()方法會喚醒所有在等待中的執行緒。這和Obejct.notify()方法類似。
condition.await()方法必須在lock.lock()與lock.unlock()方法之間呼叫。
public class ConditionExample{
public static ReentrantLock lock = new ReentrantLock();
public static Condition condition = lock.newCondition();
public static void main(String[] args) {
new Thread(() -> {
lock.lock();
out.println("執行緒1 獲得鎖");
try {
out.println("執行緒1 await");
condition.await();
out.println("執行緒1 再次獲得鎖");
} catch (InterruptedException e) {
} finally {
out.println("執行緒1 釋放鎖");
lock.unlock();
}
}).start();
new Thread(() -> {
lock.lock();
out.println("執行緒2 獲得鎖");
try {
out.println("執行緒2 notifyAll");
condition.signalAll();
} finally {
out.println("執行緒2 釋放鎖");
lock.unlock();
}
}).start();
}
}
複製程式碼
輸出:
執行緒1 獲得鎖
執行緒1 await
執行緒2 獲得鎖
執行緒2 notifyAll
執行緒2 釋放鎖
執行緒1 再次獲得鎖
執行緒1 釋放鎖
複製程式碼
經典例題:A、B、C依次列印
public class PrintOrderedABC {
ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
String type = "A";
void printA() {
lock.lock();
try {
while (!StringUtils.equals(type, "A")) {
conditionA.await();
}
out.println("print A");
} catch (InterruptedException e) {
}
type = "B";
conditionB.signal();
lock.unlock();
}
void printB() {
lock.lock();
try {
while (!StringUtils.equals(type, "B")) {
conditionB.await();
}
out.println("print B");
} catch (InterruptedException e) {
}
type = "C";
conditionC.signal();
lock.unlock();
}
void printC() {
lock.lock();
try {
while (!StringUtils.equals(type, "C")) {
conditionC.await();
}
out.println("print C");
} catch (InterruptedException e) {
}
type = "A";
conditionA.signal();
lock.unlock();
}
public static void main(String[] args) {
PrintOrderedABC printOrderedABC = new PrintOrderedABC();
Thread ta = new Thread(() -> {
for (int i = 0; i < 10; i++) {
printOrderedABC.printA();
}
});
Thread tb = new Thread(() -> {
for (int i = 0; i < 10; i++) {
printOrderedABC.printB();
}
});
Thread tc = new Thread(() -> {
for (int i = 0; i < 10; i++) {
printOrderedABC.printC();
}
});
ta.start();
tb.start();
tc.start();
}
}
複製程式碼