wait , notify 模拟 Queue

  1 package com.itdoc.multi.sync009;
  2 
  3 import java.util.LinkedList;
  4 import java.util.concurrent.TimeUnit;
  5 import java.util.concurrent.atomic.AtomicInteger;
  6 
  7 /**
  8  * @BLOG http://www.cnblogs.com/goodcheap
  9  * @DESCRIBE wait, notify 模拟 Queue
 10  * @AUTHOR WángChéngDá
 11  * @DATE 2017-03-25 9:26
 12  */
 13 public class MyQueue {
 14 
 15     //1.创建容器
 16     private LinkedList<Object> list = new LinkedList<>();
 17 
 18     //2.构建计数器
 19     private AtomicInteger count = new AtomicInteger(0);
 20 
 21     //3.设置容器的容量上下限
 22     private final int minSize = 0;
 23     private final int maxSize;
 24 
 25     //4.创建设置容器上限的构造器
 26     public MyQueue(int maxSize) {
 27         this.maxSize = maxSize;
 28     }
 29 
 30     //5.设置对象锁
 31     final Object lock = new Object();
 32 
 33     //put: 将对象放入容器中, 假如容器容量到达上限, 将线程阻塞, 等待唤醒。
 34     public void put(Object obj) {
 35         synchronized (lock) {
 36             if (this.maxSize == count.get()) {
 37                 try {
 38                     lock.wait();
 39                 } catch (InterruptedException e) {
 40                     e.printStackTrace();
 41                 }
 42             }
 43             //将对象放入容器
 44             list.add(obj);
 45             //计入计数器
 46             count.incrementAndGet();
 47             //假如一线程提取容器中元素而因为容器为空进入阻塞状态, 容器中添加元素后将其唤醒。
 48             lock.notify();
 49             System.out.println("Add a new element to " + obj);
 50         }
 51     }
 52     //take: 将对象从容器中取出, 假如容器没有任何元素, 将线程阻塞, 等待唤醒。
 53     public Object take() {
 54         Object obj = null;
 55         synchronized (lock) {
 56             if (this.minSize == count.get()) {
 57                 try {
 58                     lock.wait();
 59                 } catch (InterruptedException e) {
 60                     e.printStackTrace();
 61                 }
 62             }
 63             //获取容器中第一个元素
 64             obj = list.removeFirst();
 65             //计入计数器
 66             count.decrementAndGet();
 67             //假如一线程向容器中放入元素而因容器到达上限进入阻塞状态, 将容器第一个元素取出后将其唤醒。
 68             lock.notify();
 69             System.out.println("Remove an element to " + obj);
 70         }
 71         return obj;
 72     }
 73 
 74     public static void main(String[] args) throws InterruptedException {
 75         final MyQueue mq = new MyQueue(5);
 76         mq.put("a");
 77         mq.put("b");
 78         mq.put("c");
 79         mq.put("d");
 80         mq.put("e");
 81         System.out.println("容器中元素有: " + mq.size() + "个。");
 82 
 83         new Thread(() -> {
 84             System.out.println("Enter the " + Thread.currentThread().getName());
 85             mq.put("f");
 86             mq.put("g");
 87             System.out.println(Thread.currentThread().getName() + " Thread stop...");
 88         }, "T1").start();
 89 
 90         TimeUnit.SECONDS.sleep(2);
 91 
 92         new Thread(() -> {
 93             System.out.println("Enter the " + Thread.currentThread().getName());
 94             mq.take();
 95             mq.take();
 96             System.out.println(Thread.currentThread().getName() + " Thread stop...");
 97         }, "T2").start();
 98         /**
 99          * 解决: ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2
100          * JDWP exit error AGENT_ERROR_NO_JNI_ENV(183):  [util.c:840]
101          */
102         System.exit(0);
103     }
104 
105     private int size() {
106         return this.count.get();
107     }
108 }

控制台输出:

Add a new element to a
Add a new element to b
Add a new element to c
Add a new element to d
Add a new element to e
容器中元素有: 5个。
Enter the T1
Enter the T2
Remove an element to a
Remove an element to b
T2 Thread stop...
Add a new element to f
Add a new element to g

原文地址:https://www.cnblogs.com/chinda/p/6616478.html