package com.itdoc.multi.sync009;

 import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; /**
* @BLOG http://www.cnblogs.com/goodcheap
* @DESCRIBE wait, notify 模拟 Queue
* @AUTHOR WángChéngDá
* @DATE 2017-03-25 9:26
*/
public class MyQueue { //1.创建容器
private LinkedList<Object> list = new LinkedList<>(); //2.构建计数器
private AtomicInteger count = new AtomicInteger(0); //3.设置容器的容量上下限
private final int minSize = 0;
private final int maxSize; //4.创建设置容器上限的构造器
public MyQueue(int maxSize) {
this.maxSize = maxSize;
} //5.设置对象锁
final Object lock = new Object(); //put: 将对象放入容器中, 假如容器容量到达上限, 将线程阻塞, 等待唤醒。
public void put(Object obj) {
synchronized (lock) {
if (this.maxSize == count.get()) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//将对象放入容器
list.add(obj);
//计入计数器
count.incrementAndGet();
//假如一线程提取容器中元素而因为容器为空进入阻塞状态, 容器中添加元素后将其唤醒。
lock.notify();
System.out.println("Add a new element to " + obj);
}
}
//take: 将对象从容器中取出, 假如容器没有任何元素, 将线程阻塞, 等待唤醒。
public Object take() {
Object obj = null;
synchronized (lock) {
if (this.minSize == count.get()) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//获取容器中第一个元素
obj = list.removeFirst();
//计入计数器
count.decrementAndGet();
//假如一线程向容器中放入元素而因容器到达上限进入阻塞状态, 将容器第一个元素取出后将其唤醒。
lock.notify();
System.out.println("Remove an element to " + obj);
}
return obj;
} 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.size() + "个。"); new Thread(() -> {
System.out.println("Enter the " + Thread.currentThread().getName());
mq.put("f");
mq.put("g");
System.out.println(Thread.currentThread().getName() + " Thread stop...");
}, "T1").start(); TimeUnit.SECONDS.sleep(2); new Thread(() -> {
System.out.println("Enter the " + Thread.currentThread().getName());
mq.take();
mq.take();
System.out.println(Thread.currentThread().getName() + " Thread stop...");
}, "T2").start();
/**
* 解决: ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2
* JDWP exit error AGENT_ERROR_NO_JNI_ENV(183): [util.c:840]
*/
System.exit(0);
} private int size() {
return this.count.get();
}
}

控制台输出:

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

wait , notify 模拟 Queue的更多相关文章

  1. 1. 模拟Queue

    package com.gf.conn009; import java.util.LinkedList; import java.util.concurrent.atomic.AtomicIntege ...

  2. 模拟Queue(wait/notify)

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

  3. Codeforces Round #366 (Div. 2) C 模拟queue

    C. Thor time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...

  4. CF #366 DIV2 C. Thor 模拟 queue/stack降低复杂度

    C. Thor time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...

  5. scheme 模拟queue

    [code 1] shows a implementation of queue. The function enqueue! returns a queue in that the obj is a ...

  6. wait/notify模拟线程池

    线程创建和销毁会消耗很多的资源,当我们创建线程时,会发现cpu利用率很高,为了节省资源的使用,使用线程池是一个比较好的选择,当有任务需要执行时,随机分配给一条线程去执行,也可以删除任务,获取任务数量等 ...

  7. wait/notify模拟连接池

    连接池中的连接可重复使用,减少每次新建和烧毁连接对资源的消耗,但连接池的容量大小也要设置合理,否则也会占用多余的资源.连接池的基本功能是获取连接和释放连接 连接在java中也是一个类,连接对象是一个普 ...

  8. 用数组模拟STL中的srack(栈)和queue(队列)

    我们在理解stack和queue的基础上可以用数组来代替这两个容器,因为STL中的stack和queue有可能会导致程序运行起来非常的慢,爆TLE,所以我们使用数组来模拟他们,不仅可以更快,还可以让代 ...

  9. 话说 wait、notify 、 notifyAll

    一.前言 说起java的线程之间的通信,难免会想起它,他就是 wait .notify.notifyAll 他们三个都是Object类的方法, 受到 final 和 native 加持 ,也就造就了他 ...

随机推荐

  1. 「日常训练」Alena And The Heater (CFR466D2D)

    题意(Codeforces 940D) 根据给定要求构建数列,求能构建出相同数列的l和r. 分析 这题写的是真的烦.一定要想到对b串要按照5个5个的看!为什么5个5个的看?因为根据题意,是先看前4个再 ...

  2. 九度OJ--1163(C++)

    #include <iostream>#include <vector> using namespace std; int main() { int n; while(cin& ...

  3. python基础训练营05

    任务五 时长:2天 1.file a.打开文件方式(读写两种方式) b.文件对象的操作方法 c.学习对excel及csv文件进行操作 2.os模块 3.datetime模块 4.类和对象 5.正则表达 ...

  4. AM5728通过GPMC接口与FPGA高速数据通信实现

    硬件:AM5728开发板:Artix-7开发板软件:Linux am57xx-evm 4.4.19:Vivado 2015.2作者:杭州矢志信息科技有限公司邮箱:admin@sysjoint.com ...

  5. Drools 7.4.1.Final参考手册(六) 用户手册

    用户手册 基础 无状态的知识Session Drools规则引擎拥有大量的用例和功能,我们要如何开始?你无须担心,这些复杂性是分层的,你可以用简单的用例来逐步入门. 无状态Session,无须使用推理 ...

  6. BZOJ 3809 Gty的二逼妹子序列 莫队算法+分块

    Description Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题. 对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数. 为了方便,我们 ...

  7. 数论初步——Eratosthenes筛法

    具体内容见紫书p312-p313 一.用Eratosthenes筛法构造1~n的素数表 思想:对于不超过n的每个非负整数p,删除2p,3p,4p…,当处理完所有的数后,还没有被删除的就是素数. 代码: ...

  8. css3 移入移出动画

    css: /*css3 鼠标移入移出动画 底部出现阴影层文字叙述*/ *{;} .div1{width:300px;height: 300px;text-align: center; backgrou ...

  9. lintcode-74-第一个错误的代码版本

    74-第一个错误的代码版本 代码库的版本号是从 1 到 n 的整数.某一天,有人提交了错误版本的代码,因此造成自身及之后版本的代码在单元测试中均出错.请找出第一个错误的版本号. 你可以通过 isBad ...

  10. zuoyebiji