public class MyQueue {

    //定义一个存储数据的容器
private LinkedList<Object> list = new LinkedList<Object>(); //定义容器的最小容量
private int minSize = 0; //定义容器的最大容量
private int maxSize; //定义队列的长度
private AtomicInteger size = new AtomicInteger(0); //定义一个锁对象
private Object lock = new Object(); public MyQueue(int maxSize){
this.maxSize = maxSize;
} //put方法,向队列中假数据,如果队列满则阻塞直到有空闲的空间
public void put(Object obj){
synchronized (lock) {
while(maxSize == size.get()){
try {
//1.如果队列满,则阻塞
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//2.如果有空间了,首先添加一个元素
list.add(obj);
//3.当前的size加1
size.incrementAndGet();
System.out.println("存入元素"+obj);
//4.唤醒所有的take等待线程
lock.notify();
}
} //take方法,从队列中取数据,如果队列为空,那么阻塞直到有一个可用元素为止
public Object take(){
Object ret = null;
synchronized (lock) {
while(minSize == size.get()){
try {
//1.如果队列中没有元素,则等待
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//2.如果队列中有值了,取出值
ret = list.removeFirst();
//3.队列的长度减1
size.decrementAndGet();
//4.唤醒所有的put等待线程
lock.notify();
System.out.println("取出元素"+ret);
}
return ret;
} //得到当前的长度
public int getSize(){
return size.get();
} public static void main(String[] args) throws InterruptedException { final MyQueue myQueue = new MyQueue(5);
myQueue.put("1");
myQueue.put("2");
myQueue.put("3");
myQueue.put("4");
myQueue.put("5"); System.out.println("myQueue的长度是:"+myQueue.getSize()); Thread t1 = new Thread(new Runnable() {
public void run() {
myQueue.put("6");
myQueue.put("7");
}
},"t1"); t1.start(); TimeUnit.SECONDS.sleep(5); Thread t2 = new Thread(new Runnable() {
public void run() {
myQueue.take();
myQueue.take();
}
},"t1");
t2.start();
} }

执行结果:

存入元素1
存入元素2
存入元素3
存入元素4
存入元素5
myQueue的长度是:
取出元素1
取出元素2
存入元素6
存入元素7

使用notiy和wait模拟阻塞队列的更多相关文章

  1. java多线程系列10 阻塞队列模拟

    接下来的几篇博客会介绍下juc包下的相关数据结构 包含queue,list,map等 这篇文章主要模拟下阻塞队列. 下面是代码 import java.util.LinkedList; import ...

  2. java并发编程学习: 阻塞队列 使用 及 实现原理

    队列(Queue)与栈(Stack)是数据结构中的二种常用结构,队列的特点是先进先出(First In First Out),而Stack是先进后出(First In Last Out),说得通俗点: ...

  3. [Java 基础] 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    reference : http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html 在Java多线程应用中,队列的使用率很高,多数生 ...

  4. 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...

  5. lesson2:java阻塞队列的demo及源码分析

    本文向大家展示了java阻塞队列的使用场景.源码分析及特定场景下的使用方式.java的阻塞队列是jdk1.5之后在并发包中提供的一组队列,主要的使用场景是在需要使用生产者消费者模式时,用户不必再通过多 ...

  6. 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法(转)

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...

  7. Java多线程高并发学习笔记——阻塞队列

    在探讨可重入锁之后,接下来学习阻塞队列,这边篇文章也是断断续续的写了很久,因为最近开始学ssm框架,准备做一个自己的小网站,后续可能更新自己写网站的技术分享. 请尊重作者劳动成果,转载请标明原文链接: ...

  8. 并发库应用之十一 & 阻塞队列的应用

    队列包含固定长度的队列和不固定长度的队列,队列的规则就是:先进先出.固定长度的队列往里放数据,如果放满了还要放,阻塞式队列就会等待,直到有数据取出,空出位置后才继续放:非阻塞式队列不能等待就只能报错了 ...

  9. BlockingQueue 阻塞队列实现异步事件

    转载请注明出处:https://www.cnblogs.com/wenjunwei/p/10411444.html 前言 本文通过一个简单的例子,来展现如何使用阻塞队列(BlockingQueue)来 ...

随机推荐

  1. Using Redis as Django's session store and cache backend

    http://michal.karzynski.pl/blog/2013/07/14/using-redis-as-django-session-store-and-cache-backend/

  2. poj 1258 Agri-Net 最小生成树 kruskal

    点击打开链接 Agri-Net Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 33733   Accepted: 13539 ...

  3. java常用面板

    public class JPanelTest extends JFrame{    public JPanelTest(){        Container c=getContentPane(); ...

  4. 【摘】linux之shutdown、halt和reboot命令详解

    在重新启动Linux系统的同时把内存中的信息写入硬盘,应使用()命令实现 #shutdown -r now #halt #reboot #init3 正确答案:A   在linux命令中reboot是 ...

  5. 《Code Complete》ch.15 使用条件语句

    WHAT? 条件语句指if.else.case.switch,循环语句指for.while WHY? 不用条件语句你写得出代码吗? HOW? if-then 正常情况放在异常情况之前 执行频率高的情况 ...

  6. 使用升级版的 Bootstrap typeahead v1.2.2

    上次介绍了 Bootstrap 2 中附带的 typeahead,功能强大,但是使用起来不太方便,作者 Terry Rosen 已经升级了一个新版本 v1.2.2,作出了很大的改进. 下载地址 htt ...

  7. 欧拉路径Hrbust1351

    http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1351 这道题先利用并查集的知识点, ...

  8. android界面布局技巧(一)

    (1)//得到手机的宽高 Display display = getWindowManager().getDefaultDisplay(); int screenWidth = display.get ...

  9. 【HTTP】POST 与 PUT 方法区别

    1. POST 用于向服务端发送数据,常用于表单数据提交: PUT   用于向服务器上的资源(如文件)中存储数据: 2. 302 303 307 状态码区别 他们都是重定向(临时重定向 p.s 301 ...

  10. contentSize、contentInset和contentOffset的区分

    一.  frame.bounds和center的区分 frame:由左边原点和矩形面积组成,其中原点代表其在父视图中的起点位置. bounds:就是原点始终为(0,0)的frame. center:本 ...