Condition是在java 1.5中才出現的,它用來替代傳統的Object的wait()、notify()實現線程間的協作,相比使用Object的wait()、notify(),使用Condition的await()、signal()這種方式實現線程間協作更加安全和高效。因此通常來說比較推薦使用Condition,阻塞隊列實際上是使用了Condition來模擬線程間協作。
- Condition是個接口,基本的方法就是await()和signal()方法
- Condition依賴於Lock接口,生成一個Condition的基本代碼是lock.newCondition()
- 調用Condition的await()和signal()方法,都必須在lock保護之內,就是說必須在lock.lock()和lock.unlock之間纔可以使用
- Conditon中的await()對應Object的wait()
- Condition中的signal()對應Object的notify()
- Condition中的signalAll()對應Object的notifyAll()
多線程下使用
public class ConditionTest2 {
private final static Lock lock = new ReentrantLock();
private final static Condition PRODUCE_COND = lock.newCondition();
private final static Condition CONSUME_COND = lock.newCondition();
private final static LinkedList<Long> TIMESTAMP_POOL = new LinkedList<>();
private final static int MAX_CAPACITY = 100;
public static void produce(){
try {
lock.lock();
while(TIMESTAMP_POOL.size() >= MAX_CAPACITY){
PRODUCE_COND.await();
}
long value = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + "-p-" + value);
TIMESTAMP_POOL.addLast(value);
CONSUME_COND.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void consume(){
try {
lock.lock();
while (TIMESTAMP_POOL.isEmpty()){
CONSUME_COND.await();
}
long value = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + "-C-" + value);
PRODUCE_COND.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
// 測試的時候,線程中請加上時間sleep
new Thread(()->{
for (;;){
produce();
}
}).start();
new Thread(()->{
for (;;){
produce();
}
}).start();
new Thread(()->{
for (;;){
consume();
}
}).start();
new Thread(()->{
for (;;){
consume();
}
}).start();
}
}
https://blog.csdn.net/fuyuwei2015/article/details/72602182
這裏講的很詳細