java多執行緒--condition條件
阿新 • • 發佈:2018-12-31
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[5]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); //獲取鎖 try { // 如果“緩衝已滿”,則等待;直到“緩衝”不是滿的,才將x新增到緩衝中。 while (count == items.length) notFull.await(); // 將x新增到緩衝中 items[putptr] = x; // 將“put統計數putptr+1”;如果“緩衝已滿”,則設putptr為0。 if (++putptr == items.length) putptr = 0; // 將“緩衝”數量+1 ++count; // 喚醒take執行緒,因為take執行緒通過notEmpty.await()等待 notEmpty.signal(); // 列印寫入的資料 System.out.println(Thread.currentThread().getName() + " put "+ (Integer)x); } finally { lock.unlock(); // 釋放鎖 } } public Object take() throws InterruptedException { lock.lock(); //獲取鎖 try { // 如果“緩衝為空”,則等待;直到“緩衝”不為空,才將x從緩衝中取出。 while (count == 0) notEmpty.await(); // 將x從緩衝中取出 Object x = items[takeptr]; // 將“take統計數takeptr+1”;如果“緩衝為空”,則設takeptr為0。 if (++takeptr == items.length) takeptr = 0; // 將“緩衝”數量-1 --count; // 喚醒put執行緒,因為put執行緒通過notFull.await()等待 notFull.signal(); // 列印取出的資料 System.out.println(Thread.currentThread().getName() + " take "+ (Integer)x); return x; } finally { lock.unlock(); // 釋放鎖 } } } public class ConditionTest2 { private static BoundedBuffer bb = new BoundedBuffer(); public static void main(String[] args) { // 啟動10個“寫執行緒”,向BoundedBuffer中不斷的寫資料(寫入0-9); // 啟動10個“讀執行緒”,從BoundedBuffer中不斷的讀資料。 for (int i=0; i<10; i++) { new PutThread("p"+i, i).start(); new TakeThread("t"+i).start(); } } static class PutThread extends Thread { private int num; public PutThread(String name, int num) { super(name); this.num = num; } public void run() { try { Thread.sleep(1); // 執行緒休眠1ms bb.put(num); // 向BoundedBuffer中寫入資料 } catch (InterruptedException e) { } } } static class TakeThread extends Thread { public TakeThread(String name) { super(name); } public void run() { try { Thread.sleep(10); // 執行緒休眠1ms Integer num = (Integer)bb.take(); // 從BoundedBuffer中取出資料 } catch (InterruptedException e) { } } } }