用wait/notify 模擬Queue

一、BlockingQueue支持阻塞隊列
   此例子主要是模擬LinkBlockingQueue中put和take方法

public class SimulationQueue {
    // 1 裝載元素的容器
    private final List<Object> list = Lists.newArrayList();
    // 2 計數器
    private final AtomicInteger count = new AtomicInteger(0);
    // 3 確定容器的上限和下限
    private Integer maxSize;
    private Integer minSize;

    // 4 構造初始值
    public SimulationQueue(int maxSize) {
        this.maxSize = maxSize;
    }

    // 5 初始化一個對象,用於加鎖
    private Object lock = new Object();


    /**
     * put(an object) 把an object加到BlockingQueue裏面,如果BlockingQueue沒有空間
     * 調用此方法的線程被阻斷,直到BlockingQueue,有空間添加數據
     *
     * @param obj
     */
    public void put(Object obj) {
        synchronized (lock) {
            while (count.get() == maxSize) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 1 容器中添加元素
            list.add(obj);
            // 2 計數器加1
            count.incrementAndGet();
            System.out.println("新加入的元素爲:" + obj);
            // 3 通知其他線程(喚醒)
            lock.notify();
        }
    }

    /**
     * take() 取走排在BlockingQueue裏面排在首位的元素,如果BlockingQueue爲空
     * 阻斷進入等待狀態,直到BlockingQueue有新的數據加入
     */
    public Object take() {
        Object ret = null;
        synchronized (lock) {
            while (count.get() == 0) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 1 容器中取出排在首位的元素
            Object firstObj = list.remove(0);
            // 2 計數器遞減
            count.decrementAndGet();
            // 3 通知其他線程(喚醒)
            lock.notify();
        }
        return ret;
    }

    public int size() {
        return count.get();
    }

    public static void main(String[] args) throws  Exception {

        final SimulationQueue m = new SimulationQueue(5);
        m.put("a");
        m.put("b");
        m.put("c");
        m.put("d");
        m.put("e");
        System.out.println("當前元素個數:" + m.size());
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                m.put("h");
                m.put("i");
            }
        }, "t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    Object t1 = m.take();
                    //System.out.println("被取走的元素爲:" + t1);
                    Thread.sleep(1000);
                    Object t2 = m.take();
                    //System.out.println("被取走的元素爲:" + t2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "t2");

        t1.start();
        Thread.sleep(1000);
        t2.start();

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