Java併發編程:併發Queue接口

隊列是一種先進先出或者後進後出的數據結構。在此我們模擬一下隊列這種數據結構:
MyQueue.java定義如下:

public class MyQueue {

    //隊列的容器
    private LinkedList<Object> list = new LinkedList<Object>();

    //計數器 int count
    private final AtomicInteger count = new AtomicInteger(0);

    //最大容量
    private int maxSize;

    //最小容量
    private int  minSize = 0;

    //鎖
    private final Object lock = new Object();

    public MyQueue() {
        this(16);
    }

    public MyQueue(int maxSize) {
        this.maxSize = maxSize;
    }

    public void put(Object obj) {
        synchronized (lock) {
            while(count.get() == maxSize) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            list.add(obj); //將新的元素添加到容器裏
            System.out.println("新增前容器長度:" + count.get());
            count.getAndIncrement();
            System.out.println("新增後容器長度:" + count.get());
            lock.notify(); //喚醒線程
        }
    }

    public Object take() {
        Object temp = null;
        synchronized (lock) {
            while(count.get() == minSize) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            temp = list.removeFirst(); //從容器中移除第一個元素
            System.out.println("自減之前的長度:" + count.get());
            count.getAndDecrement();
            System.out.println("自減之後的長度:" + count.get());
            lock.notify();
        }
        return temp;
    }

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

    public List<Object> getQueueList() {
        return list;
    }
}

該隊列的數據結構爲一個List< Object> 作爲容器來盛裝數據,此外還有幾個變量,分別是count計數器和maxSize,minSize最大最小容量的標誌,此外還有lock鎖。此類有3個核心方法,分別是size()返回隊列長度的方法,take()移除節點方法和put()添加節點方法。

該隊列的測試類定義如下:

public class TestMyQueue {

    public static void main(String[] args) throws Exception {
        MyQueue queue = new MyQueue(5);
        queue.put("A");
        queue.put("B");
        queue.put("C");
        queue.put("D");
        queue.put("E");
        System.out.println("主線程queue : " + queue);

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                queue.put("F");
                queue.put("G");
            }
        }, "t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    queue.take();

                    Thread.sleep(1000);
                    queue.take();
                }catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "t2");

        t1.start();

        Thread.sleep(1000);
        t2.start();
        Thread.sleep(5000);
        List<Object> elements = queue.getQueueList();
        for(Object obj : elements) {
            System.out.print(obj.toString() + " ");
        }
    }
}

該測試類除了main函數所在的主線程之外還存在兩個子線程t1,t2。線程t1負責向容器大小爲5的隊列容器放入"F"和"G"元素,線程t2則負責向隊列移除頭部節點。
輸出結果如下:

主線程queue : com.springchang.threadcore.celection.MyQueue@49476842
C D E F G 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章