使用LinkedList实现安全队列

来源:互联网 发布:sql server是什么意思 编辑:程序博客网 时间:2024/05/19 23:05


         使用 wait notify 实现一个队列,队列有2个方法,add 和 get 。add方法往队列中添加元素,get方法往队列中获得元素。队列必须是线程安全的。如果get执行时,队列为空,线程必须阻塞等待,直到有队列有数据。如果add时,队列已经满,则add线程要等待,直到队列有空闲空间。 


        

/** * 使用LinkedList实现安全队列 * */public class SafeLinkedList<E> {    private LinkedList<E> data = new LinkedList<>();    private int totalSize;    public SafeLinkedList(int totalSize) {        this.totalSize = totalSize;    }    /**     * 当队列已满时候,阻塞,直到取走数据为止     * @param e     */    public void add(E e) {        synchronized (data) {            if (data.size() == totalSize) {                try {                    data.wait();                } catch (InterruptedException e1) {                    Thread.interrupted();                    data.notifyAll();                    System.out.println("队列已满啦!");                }            }            data.add(e);            data.notifyAll();        }    }    /**     * 当队列为空时候,阻塞等待     * @return     */    public E get() {        synchronized (data) {            if (data.isEmpty()) {                try {                    data.wait();                } catch (InterruptedException e) {                    Thread.interrupted();                    data.notifyAll();                }            }            E e = data.getFirst();//获取队列头元素            data.removeFirst();//移除对头元素            data.notifyAll();            return e;        }    }    public synchronized int size() {        return data.size();    }}



测试队列:


/** * 多线程条件下测试LinkedList存取数据是否安全 */public class SafeLinkedListTest {    private SafeLinkedList<String> data = new SafeLinkedList<>(10);    @Test    public void putGetTest() throws InterruptedException {        //add test        Thread t1 = new Thread(new OperAddThread());        Thread t2 = new Thread(new OperAddThread());        Thread t3 = new Thread(new OperAddThread());        Thread getThread = new Thread(new OperGetThread());        getThread.setName("getThread");        t1.start();        t2.start();        t3.start();        getThread.start();        t1.join();        t2.join();        t3.join();        getThread.join();        System.out.println(data.size());    }    class OperAddThread implements Runnable {        @Override        public void run() {            for (int i = 0; i < 4; i++) {                String addData=Thread.currentThread().getName()+"|"+String.valueOf(i);                data.add(addData);                System.out.println("add size=" + data.size());                System.out.println(Thread.currentThread().getName() + " addData=" + addData);            }        }    }    class OperGetThread implements Runnable {        @Override        public void run() {            int i=11;            while (i>=0) {                i--;                String value = data.get();                System.out.println("get size=" + data.size());                System.out.println("get string--" + " ;value=" + value);            }        }    }}