自定義阻塞隊列

自定義阻塞隊列

這個自定義阻塞隊列基本就是jdk阻塞隊列的實現

public class MyBlockQueue<E> {
    /**
     * 鎖 保證併發安全
     */
    private ReentrantLock lock = new ReentrantLock();

    /**
     * 隊列元素
     */
    private final Object[] items;

    /**
     * 取元素的下標
     */
    private int takeIndex;

    /**
     * 放元素的下標
     */
    private int putIndex;

    /**
     * 隊列中元素的個數
     */
    private int count;

    /**
     * 用於隊列空的時候阻塞
     */
    private Condition isEmpty = lock.newCondition();

    /**
     * 用於隊列滿的時候阻塞
     */
    private Condition isFull = lock.newCondition();

    public MyBlockQueue(){
        this(16);
    }

    public MyBlockQueue(int len) {
        // 隊列長度不能小於0
        if (len < 0)
            throw new IllegalArgumentException("param is illegal");
        this.items = new Object[len];
    }

    public void put(E e) throws InterruptedException {
        // 加鎖
        lock.lock();
        try{
            // 當隊列滿的時候線程阻塞
            while (count == items.length)
                isFull.await();
            items[putIndex] = e;
            // 判斷隊列是否插完,是的話就開始從第一個開始插
            if (++putIndex == items.length)
                putIndex = 0;
            // 元素個數加1
            count++;
            // 每插入一個元素就要喚醒阻塞在isEmpty上的線程
            isEmpty.signal();
            System.out.println(Thread.currentThread().getName() + ":放入元素,當前隊列中有元素:" + count + "個");
        }finally {
           lock.unlock();
        }
    }

    public E take() throws InterruptedException {
        lock.lock();
        try{
            // 隊列爲空的時候阻塞
            while (count == 0)
                isEmpty.await();
            E item = (E)items[takeIndex];
            items[takeIndex] = null;
            // 元素個數減1
            count--;
            // 當takeIndex和數組長度相等的時候證明數組中元素已經取完
            if (++takeIndex == items.length)
                takeIndex = 0;
            // 保證下次取的時候數組不越界
            if (takeIndex > 0) takeIndex--;
            // 每獲取一個線程就要喚醒阻塞在isFull上的線程
            isFull.signal();
            System.out.println(Thread.currentThread().getName() + ":取出元素,當前隊列中有元素:" + count + "個");
            return item;
        }finally {
            lock.unlock();
        }
    }

    /**
     * 獲取隊列中元素個數
     * @return
     */
    public int getCount() {
        return count;
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章