模拟阻塞队列-使用notify和wait

阻塞队列BlockingQueue,在容器满的时候,放入元素,会被阻塞,等到容器中元素被取走时,才可以放入;当容器为空的时候,无法从容器取出元素,当有元素放入时,才可以从容器中取走。

/**

 * 模拟阻塞队列

 */

public class MyQueue {

   // 1、定义容器

   privateLinkedList<Object> list = newLinkedList<Object>();

   // 2、设置最小和最大容量

   private int minSize = 0;

   private int maxSize;

   // 3、设置计数器

   private AtomicInteger count = newAtomicInteger(0);

   // 4、对象锁,这里一把锁,就可以实现,因为不可能同时阻塞

   private final Object lock = new Object();

 

   // 在声明对象时,给队列长度赋值

   public MyQueue(int maxSize) {

      this.maxSize = maxSize;

   }

 

   /*

    *put()把对象加入BlockingQueue中,如果BlockQueue没有空间,则

    * 调用此方法的线程被阻塞,知道BlockingQueue里面有空间再继续

    */

   public voidput(Object obj) {

      synchronized (lock) {

        while (count.get() == this.maxSize) {// 如果队列放满了,则阻塞

           try {

              lock.wait();

           } catch(InterruptedException e) {

              e.printStackTrace();

           }

        }

        list.add(obj);

        count.incrementAndGet();

        lock.notify();

        System.out.println("放入了元素:" + obj);

      }

   }

 

   /*

    * 取走BlockingQueue里排在首位的对象,如果为空BlockingQueue为空,则阻塞进入等待状态直到里有新的数据加入

    */

   public Object take() {

      Object ret = null;

      synchronized (lock) {

        while (count.get() == this.minSize) {

           try {

              lock.wait();

           } catch(InterruptedException e) {

              e.printStackTrace();

           }

        }

        ret = list.removeFirst();

        lock.notify();

        count.decrementAndGet();

        System.out.println("取出了元素:" + ret);

      }

      return ret;

   }

 

   public static voidmain(String[] args) {

      final MyQueue mq = newMyQueue(5);

      mq.put("a");

      mq.put("b");

      mq.put("c");

      mq.put("d");

      mq.put("e");

      // 放入两个元素,

      new Thread(newRunnable() {

        @Override

        public void run() {

           mq.put("e");

           mq.put("f");

        }

      }).start();

      // 休眠2

      try {

        TimeUnit.SECONDS.sleep(2);

      } catch(InterruptedException e) {

        e.printStackTrace();

      }

      new Thread(newRunnable() {

        @Override

        public void run() {

           mq.take();

           mq.take();

        }

      }).start();

   }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值