1. 程式人生 > >java多執行緒--condition條件

java多執行緒--condition條件

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) {
            }
        }
    }
}