使用Condition實現多執行緒之間呼叫
阿新 • • 發佈:2019-01-01
一,object 類的wait,notify和notifyAll
Java 執行緒類也是一個object 類,它的例項都繼承自java.lang.Thread 或其子類。wait,notify和notifyAll是Object類中的方法,常用於執行緒之間排程。
執行緒無資料執行可呼叫wait讓執行緒等待,不佔用CUP資源,提高CPU有效的利用率。例如,執行緒 B 可以等待執行緒 A 的一個訊號,這個訊號會通知執行緒 B 資料已經準備好了,B可以執行業務邏輯。
執行緒之間排程常應用於生產與消費模式下。
利用Object 物件的wait,notify和notifyAll可以實現,但JDK1.5後有更好的替代方法。
二,Condition 類增強類
Condition 類,實現執行緒間的協作,相比使用Object的wait、notify,使用Condition的await、signal這種方式實現執行緒間協作更加安全和高效。因此通常來說比較推薦使用Condition。
Condition依賴於Lock介面,生成一個Condition的基本程式碼是lock.newCondition 呼叫Condition的await和signal方法,必須在lock.lock和lock.unlock之間才可以使用
三,Object與Conditon 對比
Conditon中的await對應Object的wait;
Condition中的signal對應Object的notify;
Condition中的signalAll對應Object的notifyAll。
四,使用Condition 實現生產消費
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; } }