@[toc]
1.作用
- 當線程1需要等待某個條件的時候 ,它就去執行 condition.await() 方法,一旦執行了 await()方法,線程就會進入阻塞狀态
- 然後通常會有另外一個線程,假設是線程2,去執行對應的條件,知道這個條件成立,線程2就會去執行condition.signal() 方法,這是 JVM 就會被從阻塞的線程裡找到那些等待該condition的線程,當線程1就會收到可執行信号的時候,他的線程狀态就會變成Runnable 可執行狀态
signalAll() 和signal() 差別
: signalAll() 會喚醒所有的正在等待的線程
: 但是signal是公平的,隻會喚起那個等待時間最長的線程
package com.yxl.task;
import lombok.SneakyThrows;
import org.omg.PortableInterceptor.INACTIVE;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* Condition 示範demo
*/
public class ConditionDemo {
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
//方法1
void method1(){
lock.lock();
try {
System.out.println("條件不滿足,開始await");
condition.await();
System.out.println("條件滿足了,開始執行後續");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
//方法2
void method2() {
lock.lock();
try {
System.out.println("準備工作完成,喚醒其他線程 ");
condition.signal();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
ConditionDemo conditionDemo =new ConditionDemo();
new Thread(new Runnable() {
@SneakyThrows
@Override
public void run() {
Thread.sleep(1000);
conditionDemo.method2();
}
}).start();
conditionDemo.method1();
}
}
執行結果:
條件不滿足,開始await
準備工作完成,喚醒其他線程
條件滿足了,開始執行後續
2.代碼示範
- 生産着消費者案例
package com.yxl.task;
import lombok.SneakyThrows;
import org.omg.PortableInterceptor.INACTIVE;
import org.omg.PortableServer.THREAD_POLICY_ID;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* Condition 實作生産者 消費者
*/
public class ConditionDemo {
private int queueSize = 10 ;
//隊列
private PriorityQueue queue =new PriorityQueue(queueSize);
//lock鎖
private ReentrantLock lock = new ReentrantLock();
private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition();
//方法1
class Consumer extends Thread {
@SneakyThrows
@Override
public void run() {
comsume();
}
private void comsume() throws InterruptedException {
while (true){
lock.lock();
try {
while (queue.size() == 0) {
System.out.println("隊列空,等待資料");
notEmpty.await();
}
queue.poll();
notFull.signalAll();
System.out.println("從隊列裡驅走了一個資料,剩下"+ queue.size());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
class Produce extends Thread {
@SneakyThrows
@Override
public void run() {
produce();
}
private void produce() throws InterruptedException {
while (true){
lock.lock();
try {
while (queue.size() == queueSize) {
System.out.println("隊列滿,等待空閑");
notFull.await();
}
queue.offer(1);
notEmpty.signalAll();
System.out.println("向隊列插入一個元素"+ queue.size());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
public static void main(String[] args) {
ConditionDemo conditionDemo =new ConditionDemo();
Produce produce = conditionDemo.new Produce();
Consumer consumer = conditionDemo.new Consumer();
consumer.start();
produce.start();
}
}

#
有興趣的同學可以看下源碼實作 和 JDK 介紹
- 個人部落格位址: http://blog.yanxiaolong.cn/