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();
}
}
复制代码