• 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

  • 相关阅读:
    sudo配置临时取得root权限
    Linux 前台 和 后台进程 说明
    延迟加载
    事件代理
    字符串方法总结
    javascript
    HTML
    通用样式,如清除浮动
    html脱离文档流事件
    经典容易忽略的行内块
  • 原文地址:https://www.cnblogs.com/chinda/p/6616478.html
Copyright © 2020-2023  润新知