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; } }