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. 【Leetcode】647. Palindromic Substrings

    Description Given a string, your task is to count how many palindromic substrings in this string. Th ...

  2. python2.7入门---Number(数字)

        今天咱们来简单分享一下关于python中的一种数据类型和操作方法.费话不多说哈,咱们直接来进行实践加理论.首先,我们要知道,Python Number 数据类型用于存储数.数据类型是不允许改变 ...

  3. django序列化时间

    具体代码: import json,time,datetime lis ={'time':datetime.date.today(),"username":"zhilei ...

  4. java_hdfs之读写文件

    package hdfsTest.answer.hdfs; import java.io.IOException; import java.net.URI; //import java.net.URL ...

  5. 第十五篇 Python之文件处理

    一 文件操作  介绍 计算机系统分为:计算机硬件,操作系统,应用程序三部分. 我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众所 ...

  6. Truffle基础篇-Truffle做什么的?怎么安装?

    Truffle基础篇-Truffle做什么的?怎么安装? truffle资料汇总 http://truffle.tryblockchain.org/truffle3.0-integrate-nodej ...

  7. apollo命令行传入参数

    Java apollo客户端运行配置 需要在META-INF中创建app.properties文件,以配置app.id 还需要在/opt/settings/server.properties或C:/o ...

  8. linux文件系统(ext2)

    一个磁盘可以划分成多个分区,每个分区必须先用格式化工具(例如某种mkfs命令)格式化成某种格式的文件系统,然后才能存储文件,格式化的过程会在磁盘上写一些管理存储布局的信息.下图是一个磁盘分区格式化成e ...

  9. 关于debian配置的问题汇总

    debian的apache多域名配置: https://www.digitalocean.com/community/tutorials/how-to-set-up-apache-virtual-ho ...

  10. PAT 1089 狼人杀-简单版

    https://pintia.cn/problem-sets/994805260223102976/problems/1038429385296453632 以下文字摘自<灵机一动·好玩的数学& ...