• 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
  • 相关阅读:
    虚拟主机支持apk
    pc显示,手机隐藏
    manjaro个人配置
    docker-compose部署elk
    docker-compose部署zk和kafka
    docker-compose部署redis-cluster
    ActiveMQ与RocketMQ对比
    dropbox离线安装包--需FQ
    C++实现中缀表达式转前、后缀
    运算符优先级
  • 原文地址:https://www.cnblogs.com/syousetu/p/6729096.html
Copyright © 2020-2023  润新知