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

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

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

  1. public class MyQueue {
    //1 需要一个承装元素的集合
    private final LinkedList<Object> list = new LinkedList<Object>();
  2.  
  3. //2 需要一个计数器
    private AtomicInteger count = new AtomicInteger(0);
  4.  
  5. //3需要制定上限和下限
    private final int minSize = 0;
    private final int maxSize;
  6.  
  7. //4构造方法
    public MyQueue(int maxSize) {
    this.maxSize = maxSize;
    }
  8.  
  9. //5初始化一个对象,用于加锁
    private final Object lock = new Object();
  10.  
  11. public void put(Object obj) {
    synchronized (lock) {
    while (count.get() == this.maxSize) {
    try {
    lock.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    //1 加入元素
    list.add(obj);
    //2 计数器累加
    count.incrementAndGet();
    System.out.println("新加入的元素为: " + obj);
    //3 通知另外一个线程(唤醒)
    lock.notify();
    }
    }
  12.  
  13. public Object take() {
    Object ret = null;
    synchronized (lock) {
    while (count.get() == this.minSize) {
    try {
    lock.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    //1移除元素操作
    ret = list.removeFirst();
    //2计数器递减
    count.decrementAndGet();
    //3唤醒另外一个线程
    lock.notify();
    }
    return ret;
    }
  14.  
  15. public int getSize() {
    return this.count.get();
    }
  16.  
  17. public static void main(String[] args) throws InterruptedException {
    final MyQueue mq = new MyQueue(5);
    mq.put("a");
    mq.put("b");
    mq.put("c");
    mq.put("d");
    mq.put("e");
    System.out.println("当前容器的长度: " + mq.getSize());
    Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
    mq.put("f");
    mq.put("g");
    }
    }, "t1");
    t1.start();
    Thread t2 = new Thread(new Runnable() {
    @Override
    public void run() {
    Object o1 = mq.take();
    System.out.println("移除的元素为 :" + o1);
    Object o2 = mq.take();
    System.out.println("移除的元素为 :" + o2);
    }
    }, "t2");
    try {
    TimeUnit.SECONDS.sleep(2);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    t2.start();
    }
    }
  18.  
  19. 看一下这段代码的运行结果:

t1线程是在t2线程之前执行的,但是实际的运行结果是等待容器内部移除一个元素之后,才能在原来的容器里面添加新的元素,同理,在移除的时候,也要保证容器里面存在元素,不然就只能等待新的元素被加入,否则将一直处理阻塞状态。

  1.  

queue模拟的更多相关文章

  1. Codeforces 767B. The Queue 模拟题

    B. The Queue time limit per test:1 second memory limit per test:256 megabytes input:standard input o ...

  2. ACM程序设计选修课——1044: (ds:队列)打印队列(queue模拟)

    问题 A: (ds:队列)打印队列 时间限制: 1 Sec  内存限制: 128 MB 提交: 25  解决: 4 [提交][状态][讨论版] 题目描述 网络工程实验室只有一台打印机,它承担了非常繁重 ...

  3. queue+模拟 Codeforces Round #304 (Div. 2) C. Soldier and Cards

    题目传送门 /* 题意:两堆牌,每次拿出上面的牌做比较,大的一方收走两张牌,直到一方没有牌 queue容器:模拟上述过程,当次数达到最大值时判断为-1 */ #include <cstdio&g ...

  4. 剑指offer——stack与queue的互相实现

    我们知道,stack和queue是C++中常见的container.下面,我们来探究下如何以stack来实现queue,以及如何用queue来实现stack. 首先,先了解下stack与queue的基 ...

  5. 线程queue

    import queue q = queue.Queue() #模拟队列,先进先出 q.put('first') q.put('second') q.put('third') print(q.get( ...

  6. jQuery使用(九):队列及实现原理、基于队列模拟实现animate()

    开篇一张图之队列模型 queue()如何使用? queue()原理实现? 基于queue()模拟实现animate() 一.使用queuer方法.理解队列原理 queue() dequeue() cl ...

  7. 了解Queue

    在并发队列上JDK提供了两套实现,一个是以ConcurrentLinkedQueue为代表的高性能队列,一个是以BlockingQueue接口为代表的阻塞队列,无论哪种都继承自Queue, 可以对应着 ...

  8. Java-集合第四篇Queue集合

    1.什么是Queue 模拟队列数据结构,先进先出(FIFO),从队尾加元素,从队头取元素.     2.Queue接口中定义了如下几个方法: 1>void add(Object o):将指定元素 ...

  9. 杭电ACM分类

    杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze ...

随机推荐

  1. VC中链接错误,提示string重定义

    VC链接错误,说是string已经有了实现了,只要 rebuild 一下好了. Linking...LINK : warning LNK4075: ignoring '/EDITANDCONTINUE ...

  2. Centos下lnmp正确iptables配置规则

    查看iptable运行状态 service iptables status 清除已有规则 iptables -Fiptables -Xiptables -Z 开放端口 #允许本地回环接口(即运行本机访 ...

  3. 一个简单的SignalR例子

    本文介绍如何使用SignalR的Hub制作一个简单的点赞页面.不同浏览器(或者不同窗口)打开同一个页面,在任何一个页面点赞,所有页面同时更新点赞数. 1.使用Visual Studio Communi ...

  4. 【原创】字典攻击教务处(BurpSuite使用)

    0x00 本例使用Burp Suite跑字典爆破教务处登录. 使用账户名:yanjiushengdadui 本示例将结合说明Burp Suite的基本使用. 0x01 BurpSuite代理配置 浏览 ...

  5. Nodejs 菜鸟教程学习-创建第一个应用

    注:为了解学习,都是参照http://www.runoob.com/nodejs/nodejs-tutorial.html书写,做下笔记. 对于Nodejs开发来说,在开发一个应用时,我们不仅仅是实现 ...

  6. 12.JDBC-mysql.md

    目录 API简述 Driver接口: 表示java驱动程序接口.所有的具体的数据库厂商要来实现此接口. DriverManager类: 驱动管理器类,用于管理所有注册的驱动程序 Connection接 ...

  7. sqlalchemy sql express language

    metadata = MetaData() teacher = Table("teachers", metadata, Column("tid", Intege ...

  8. MongoDB分布式集群搭建

    最近在做一个关于车险的项目,由于数据量较大,实验室的Boss决定采用HBase+ES/MongoDB这两种方案,并做性能对比,本人负责MongoDB方案.为了满足海量数据的存储要求,需要搭建一个分布式 ...

  9. rename批量修改文件并在后缀前加字段

    rename   's/\.jpg$/generate_badu\.jpg/' * 其中,'.'需要加转义斜杠'\',   '*'代表文件夹下所有文件

  10. Python中struct.pack()和struct.unpack()

    https://blog.csdn.net/tjuyanming/article/details/79700601 https://www.cnblogs.com/yezl/p/5861787.htm ...