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 |