Java ReEntrantLock 之 Condition條件(Java程式碼實戰-002)

FrankYou發表於2018-05-18

 

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * ConditionTest
 * 一個測試類,用Condition實現的生產者消費者問題
 */
public class ConditionTest {
    /* 定義一個容器(連結串列、佇列) */
    private LinkedList<String> buffer;
    /* 容器可以容納元素的最大數量,通過建構函式來初始化 */
    private int maxSize;
    private Lock lock;
    private Condition fullCondition;
    private Condition notFullCondition;

    ConditionTest(int maxSize) {
        this.maxSize = maxSize;
        buffer = new LinkedList<String>();
        lock = new ReentrantLock();
        fullCondition = lock.newCondition();
        notFullCondition = lock.newCondition();
    }

    /**
     * 向容器中放入Element
     */
    public void set(String string) throws InterruptedException {
        // 獲取鎖
        lock.lock();
        try {
            while (maxSize == buffer.size()) {
                // 滿了,新增的執行緒進入等待狀態
                notFullCondition.await();
            }
            buffer.add(string);

            // 容器不為空時,則給等待的讀取的執行緒傳送訊號以便喚醒這些執行緒進行讀取
            fullCondition.signal();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 從容器中獲取Element
     */
    public String get() throws InterruptedException {
        String string;
        lock.lock();
        try {
            while (buffer.size() == 0) {
                // 如果容器為空,則讀取的執行緒進入等待狀態
                fullCondition.await();
            }
            string = buffer.poll();

            // 給寫入的執行緒傳送訊號以便喚醒這些執行緒來往容器中寫入
            notFullCondition.signal();
        } finally {
            lock.unlock();
        }
        return string;
    }
}

 

相關文章