使用notiy和wait模拟阻塞队列

 

public class MyQueue {
    
    //定义一个存储数据的容器
    private LinkedList<Object> list = new LinkedList<Object>();
    
    //定义容器的最小容量
    private int minSize = 0;
    
    //定义容器的最大容量
    private int maxSize;
    
    //定义队列的长度
    private AtomicInteger size = new AtomicInteger(0);
    
    //定义一个锁对象
    private Object lock = new Object();
    
    public MyQueue(int maxSize){
        this.maxSize = maxSize;
    }
    
    //put方法,向队列中假数据,如果队列满则阻塞直到有空闲的空间
    public void put(Object obj){
        synchronized (lock) {
            while(maxSize == size.get()){
                try {
                    //1.如果队列满,则阻塞
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //2.如果有空间了,首先添加一个元素
            list.add(obj);
            //3.当前的size加1
            size.incrementAndGet();
            System.out.println("存入元素"+obj);
            //4.唤醒所有的take等待线程
            lock.notify();
        }
    }
    
    //take方法,从队列中取数据,如果队列为空,那么阻塞直到有一个可用元素为止
    public Object take(){
        Object ret = null;
        synchronized (lock) {
            while(minSize == size.get()){
                try {
                    //1.如果队列中没有元素,则等待
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //2.如果队列中有值了,取出值
            ret = list.removeFirst();
            //3.队列的长度减1
            size.decrementAndGet();
            //4.唤醒所有的put等待线程
            lock.notify();
            System.out.println("取出元素"+ret);
        }
        return ret;
    }
    
    //得到当前的长度
    public int getSize(){
        return size.get();
    }
    
    public static void main(String[] args) throws InterruptedException {
        
        final MyQueue myQueue = new MyQueue(5);
        myQueue.put("1");
        myQueue.put("2");
        myQueue.put("3");
        myQueue.put("4");
        myQueue.put("5");
        
        System.out.println("myQueue的长度是:"+myQueue.getSize());
        
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                myQueue.put("6");
                myQueue.put("7");
            }
        },"t1");
        
        t1.start();
        
        TimeUnit.SECONDS.sleep(5);

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                myQueue.take();
                myQueue.take();
            }
        },"t1");
        t2.start();
    }
    
}

执行结果:

存入元素1
存入元素2
存入元素3
存入元素4
存入元素5
myQueue的长度是:5
取出元素1
取出元素2
存入元素6
存入元素7

 

posted @ 2016-07-29 17:20  dongdone  阅读(245)  评论(0编辑  收藏  举报