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. 动态规划(DP)算法

    参考https://blog.csdn.net/libosbo/article/details/80038549 动态规划是求解决策过程最优化的数学方法.利用各个阶段之间的关系,逐个求解,最终求得全局 ...

  2. ABAP CDS ON HANA-(12)ODATA Service

    Create a CDS view and we have the view type as ‘BASIC’ view To publish this as oData, add the annota ...

  3. python2.7入门---元组

        这次我们来学习下python中的元组.首先,基础认知点是,Python的元组与列表类似,不同之处在于元组的元素不能修改.元组使用小括号,列表使用方括号.元组创建很简单,只需要在括号中添加元素, ...

  4. 开启TCP BBR拥塞控制算法

    原文来自:https://github.com/iMeiji/shadowsocks_install/wiki/%E5%BC%80%E5%90%AFTCP-BBR%E6%8B%A5%E5%A1%9E% ...

  5. 封装一个ExcelHelper,方便将Excel直接转成Datatable对象

    public class ExcelHelper { /// <summary> /// Excel转换成DataTable /// </summary> /// <pa ...

  6. SpringBoot学习:使用logback进行日志记录

    项目下载地址:http://download.csdn.NET/detail/aqsunkai/9805821 (一)pom.xml文件中引入jar: <!-- https://mvnrepos ...

  7. 使用USB Key(加密狗)实现身份认证

    首先你需要去买一个加密狗设备,加密狗是外形酷似U盘的一种硬件设备! 这里我使用的坚石诚信公司的ET99产品 公司项目需要实现一个功能,就是客户使用加密狗登录, 客户不想输入任何密码之类的东西,只需要插 ...

  8. 今天买了个pro,开始ios开发

    今天买了个mac pro 开始ios开发啦,爽!

  9. EM算法浅析(二)-算法初探

    EM算法浅析,我准备写一个系列的文章: EM算法浅析(一)-问题引出 EM算法浅析(二)-算法初探 一.EM算法简介 在EM算法之一--问题引出中我们介绍了硬币的问题,给出了模型的目标函数,提到了这种 ...

  10. DFS(5)——hdu1728逃离迷宫

    一.题目回顾 题目链接:逃离迷宫 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地 ...