Java 線程類也是一個object 類,它的實例都繼承自java.lang.Thread 或其子類。
wait(),notify()和notifyAll()是Object類中的方法,常用於線程之間調度。
線程無數據運行可調用wait()讓線程等待,不占用CUP資源,提高CPU有效的利用率。
例如,線程 B 可以等待線程 A 的一個信號,這個信號會通知線程 B 數據已經准備好了,B可以執行業務邏輯。
線程之間調度常應用於生產與消費模式下。
利用Object 對象的wait(),notify()和notifyAll()可以實現,但JDK1.5後有更好的替代方法。
Condition 類,實現線程間的協作,相比使用Object的wait()、notify(),使用Condition的await()、signal()這種方式實現線程間協作更加安全和高效。因此通常來說比較推薦使用Condition。
Condition依賴於Lock接口,生成一個Condition的基本代碼是lock.newCondition()
調用Condition的await()和signal()方法,必須在lock.lock()和lock.unlock之間才可以使用
Conditon中的await()對應Object的wait();
Condition中的signal()對應Object的notify();
Condition中的signalAll()對應Object的notifyAll()。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by tank on 2016/11/22.
* 使用Condition 實現線程間生產消費模式
*/
public class ConditionDemo {
Object[] queue = new Object[100];//隊列
int readIndex = 0;//read索引位置
int writeIndex = 0;
int dataLen = 0;
final Lock lock = new ReentrantLock();
final Condition fullCondition = lock.newCondition();
final Condition emptyCondition = lock.newCondition();
public static void main(String[] args) {
final ConditionDemo demo = new ConditionDemo();
new Thread() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
demo.write(i);
}
}
}.start();
new Thread() {
@Override
public void run() {
while (true) {
Object obj = demo.read();
if (obj != null) {
System.out.println((Integer) obj);
}
}
}
}.start();
}
//生產
public void write(Object obj) {
lock.lock();
try {
if (dataLen >= queue.length) {//隊列寫滿了
System.out.println("隊列寫滿了,等待.....");
fullCondition.await();
System.out.println("隊列有空位了,喚醒.....");
}
queue[writeIndex] = obj;
writeIndex++;
dataLen++;
if (writeIndex >= queue.length) {
writeIndex = 0;
}
emptyCondition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
//消費
public Object read() {
lock.lock();
try {
if (dataLen <= 0) {
System.out.println("隊列空了,等待數據.....");
emptyCondition.await();
System.out.println("隊列有數據了,喚醒.....");
}
Object obj = queue[readIndex];
readIndex++;
dataLen--;
if (readIndex >= queue.length) {
readIndex = 0;
}
fullCondition.signal();
return obj;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return null;
}
}