wait/notify模拟queu

使用wait/notify模拟queue

BlockingQueue:顾名思义,首先它是一个队列,并且支持阻塞的机制,阻塞的放入和得到数据。我们要实现LinkedBlockingQueue,下面两个简单的方法put和take。

put(anObject):把anObject加到BlockingQueue,如果BlockingQueue中没有空间,则调用此方法的线程被阻断,直到BlockingQueue里有空间再继续。

take:取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入

  1 package com.java.day02_notify_wait;
  2 
  3 import java.util.LinkedList;
  4 import java.util.concurrent.atomic.AtomicInteger;
  5 
  6 /**
  7  * 用wait和notify模仿queue
  8  * 
  9  * @author syousetu
 10  *
 11  */
 12 public class MyQueue {
 13     // 先创建一个容器,有上限和下限
 14 
 15     // 1.创建一个列表
 16     private volatile LinkedList<Object> list = new LinkedList<Object>();
 17 
 18     // 2.设置列表的上限
 19     private final int max;
 20 
 21     // 3.设置列表的下限
 22     private int min = 0;
 23 
 24     // 构造器
 25     public MyQueue(int len) {
 26         this.max = len;
 27     }
 28 
 29     // 计数器
 30     private AtomicInteger count = new AtomicInteger(0);
 31 
 32     // 要使用到synchronized 所以要创建一个锁
 33     private final Object lock = new Object();
 34 
 35     // put(Object)
 36 
 37     public void put(Object obj) {
 38         synchronized (lock) {
 39             // 队列队伍已满,请等待
 40             while (count.get() == max) {
 41                 try {
 42                     lock.wait();
 43                 } catch (InterruptedException e) {
 44                     e.printStackTrace();
 45                 }
 46             }
 47 
 48             // 给列表添加元素
 49             list.add(obj);
 50             // 计数器增加一
 51             count.incrementAndGet();
 52             // 通知另外一个线程可以进行取元素
 53             lock.notify();
 54             System.out.println("已成功添加元素:" + obj);
 55 
 56         }
 57 
 58     }
 59 
 60     // take()
 61 
 62     public Object take() {
 63         Object obj = null;
 64 
 65         synchronized (lock) {
 66             // 队列里没有元素,请等待,释放锁
 67             while (count.get() == min) {
 68                 try {
 69                     lock.wait();
 70                 } catch (InterruptedException e) {
 71                     e.printStackTrace();
 72                 }
 73             }
 74 
 75             // 移除第一个元素
 76             obj = list.removeFirst();
 77             // 通知另一个线程可以进行存放
 78             lock.notify();
 79             // 计数器减一
 80             count.decrementAndGet();
 81             System.out.println("已成功取出元素");
 82 
 83         }
 84 
 85         return obj;
 86     }
 87 
 88     public int getSize() {
 89         return list.size();
 90     }
 91 
 92     public static void main(String[] args) {
 93         final MyQueue mq = new MyQueue(5);
 94         
 95         mq.put("a");
 96         mq.put("b");
 97         mq.put("c");
 98         mq.put("d");
 99         mq.put("e");
100         
101         System.out.println("当前队列的大小:"+mq.getSize());
102 
103         Thread t1  = new Thread(new Runnable() {
104             public void run() {
105                 mq.put("f");
106                 mq.put("g");
107             }
108         },"t1");
109         
110         
111         Thread t2  = new Thread(new Runnable() {
112             public void run() {
113                 for (int i = 0; i < 3; i++) {
114                     System.out.println(Thread.currentThread().getName()+"线程取出元素:"+mq.take());
115                 }
116                 
117             }
118         });
119         
120         t1.start();
121         t2.start();
122         
123     }
124 
125 }

运行结果:

 1 已成功添加元素:a
 2 已成功添加元素:b
 3 已成功添加元素:c
 4 已成功添加元素:d
 5 已成功添加元素:e
 6 当前队列的大小:5
 7 已成功取出元素
 8 Thread-0线程取出元素:a
 9 已成功添加元素:f
10 已成功取出元素
11 Thread-0线程取出元素:b
12 已成功添加元素:g
13 已成功取出元素
14 Thread-0线程取出元素:c

 

posted @ 2017-04-18 17:50  優syousetu  阅读(273)  评论(0编辑  收藏  举报