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. 12 TCP服务器 进程 线程 非阻塞

    1.单进程服务器 from socket import * serSocket = socket(AF_INET, SOCK_STREAM) # 重复使用绑定的信息 serSocket.setsock ...

  2. LeetCode:21. Merge Two Sorted Lists(Easy)

    1. 原题链接 https://leetcode.com/problems/merge-two-sorted-lists/description/ 2. 题目要求 给出两个已经从小到大排序的链表ls1 ...

  3. asp.net MVC+easyUI 文件上传

    前言:公司前端都是index页面引用js,剩下的添加...都是html页.加大操作难度5555,所以就是主页面操作子页面上传.效果如下: 1,前端html页代码如下 .其中请注意,form中encty ...

  4. crontab时间规则

    sudo crontab -e 5 * * * *每小时第5分钟执行*/5 * * * *每5分钟执行0 2 * * * 每天凌晨2点执行 cron是一个linux下的定时执行工具,可以在无需人工干预 ...

  5. Android中通过拨号调起应用的实现方式及特殊情况处理

    Android中有时我们会有这样的需求:通过拨号调起我们的程序.这个需求如何实现呢? 思路当然是在我们的应用中实现一个广播接收器(BroadcastReceiver),对打电话时系统发出的广播进行拦截 ...

  6. 使用PSSH批量操作Linux服务器

    简介 服务器多了,有一个问题就是如何批量快速操作多台服务器,在网上搜到了PSSH工具,试用了一下发现挺好用,推荐给大家. pssh是一个python编写的可以在多台服务器上执行命令的轻量级管理工具,同 ...

  7. Laxcus大数据管理系统2.0(3)- 第一章 基础概述 1.2 产品特点

    1.2 产品特点 Laxcus大数据管理系统运行在计算机集群上,特别强调软件对分布资源可随机增减的适应性.这种运行过程中数据动态波动和需要瞬时感知的特点,完全不同与传统的集中处理模式.这个特性衍生出一 ...

  8. asm和file system之间数据文件的转换

    How to move a datafile from a file system to ASMMoving a datafile from the file system can be achive ...

  9. Sersync实时备份服务部署实践

  10. z 变换

    1. z 变换 单位脉冲响应为 \(h[n]\) 的离散时间线性时不变系统对复指数输入 \(z^n\) 的响应 \(y[n]\) 为 \[ \tag{1} y[n] = H(z) z^{n}\] 式中 ...