16_Queue_利用wait()和notify()编写一个阻塞队列
【线程间通信概念】
线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体,线程间的通信就成为整体必用方式之一。当线程存在通信指挥,线程间的交互性会更强大,在提高CPU利用率的同时还会使开发人员对线程任务的处理过程中进行有效的把控和监督。
【使用wait和notify的注意点】
1.wait和notify必须配合synchronized关键字使用
2.wait方法释放锁,而notify不会释放锁
【BlockingQueue】
阻塞队列,支持阻塞的机制,阻塞地放入和得到数据。我们来自行实现LinkedBlockingQueue下面的两个简单的方法put()和take()。
[ put ]
把一个Object加到BlockingQueue里,如果BlockingQueue没有空间,则调用此方法的线程被阻塞,直到BlockingQueue里面有空间再继续。
[ take ]
取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入。
【例子】
package com.higgin.part7; import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; public class MyQueue { //1.需要一个承装元素的队列
private LinkedList<Object> list = new LinkedList<>(); //2.计数器
private AtomicInteger count = new AtomicInteger(); //3.队列的上限和下限
private final int maxSize; private final int minSize = ; //4.构造方法
public MyQueue(int size){
this.maxSize = size;
} //5.锁
private final Object lock = new Object(); /**
* 把一个对象obj添加到BlockingQueue中
* 如果BlockingQueue没有空间,则调用此方法的线程被阻断,直到BolckingQueue里面有空间
*/
public void put(Object obj){
synchronized(lock){
while(count.get() == this.maxSize){
try{
lock.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
//1.加入元素
list.add(obj);
//2.累加计数器
count.incrementAndGet();
//3.此时BlockingQueue中已经有元素,可以执行take方法,所以去唤醒take()方法
lock.notify();
System.out.println("新加入的元素为:"+obj);
}
} /**
* 取走BlockingQueue里排在首位的对象
* 若BlockingQueue为空,进入阻塞状态
*/
public Object take(){
Object ret =null;
synchronized(lock){
while(count.get() == this.minSize){
try{
lock.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
//1. 移除排在首位的元素
ret = list.removeFirst();
//2.计数器递减
count.decrementAndGet();
//3.唤醒另外一个线程
lock.notify();
}
return ret;
} public int getSize(){
return this.count.get();
} public static void main(String[] args){
final MyQueue myQueue = new MyQueue();
myQueue.put("AAA");
myQueue.put("BBB");
myQueue.put("CCC");
myQueue.put("DDD");
myQueue.put("EEE");
System.out.println("当前容器的长度:" + myQueue.getSize()); Thread t1 = new Thread(new Runnable(){
@Override
public void run() {
myQueue.put("FFF");
myQueue.put("GGG");
} },"t1");
t1.start(); Thread t2 = new Thread(new Runnable(){
@Override
public void run() {
Object o1 = myQueue.take();
System.out.println("移除的元素为:" + o1);
Object o2 = myQueue.take();
System.out.println("移除的元素为:" + o2);
} },"t2"); try {
TimeUnit.SECONDS.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
} t2.start();
}
}
【运行结果】
16_Queue_利用wait()和notify()编写一个阻塞队列的更多相关文章
- 利用ReentrantLock简单实现一个阻塞队列
借助juc里的ReentrantLock实现一个阻塞队列结构: package demo.concurrent.lock.queue; import java.util.concurrent.lock ...
- 用Java如何设计一个阻塞队列,然后说说ArrayBlockingQueue和LinkedBlockingQueue
前言 用Java如何设计一个阻塞队列,这个问题是在面滴滴的时候被问到的.当时确实没回答好,只是说了用个List,然后消费者再用个死循环一直去监控list的是否有值,有值的话就处理List里面的内容.回 ...
- 使用 ReentrantLock 和 Condition 实现一个阻塞队列
前言 从之前的阻塞队列的源码分析中,我们知道,JDK 中的阻塞队列是使用 ReentrantLock 和 Condition 实现了,我们今天来个简易版的.代码如下: 代码 public class ...
- 浅谈Java中的Condition条件队列,手摸手带你实现一个阻塞队列!
条件队列是什么?可能很多人和我一样答不出来,不过今天终于搞清楚了! 什么是条件队列 条件队列:当某个线程调用了wait方法,或者通过Condition对象调用了await相关方法,线程就会进入阻塞状态 ...
- 利用map和reduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from functools import reduce CHAR_TO_INT = { ': 0, ': ...
- [原创]如何编写多个阻塞队列连接下的多生产者多消费者的Python程序
平常在写程序时,往往会遇到一个需求:在程序的多个阶段都会出现阻塞的可能,因此,这多个阶段就需要并发执行. Python的多线程有一个特点,就是不允许从外部结束一个运行中的线程,这给我们编写代码时带来了 ...
- 用阻塞队列实现一个生产者消费者模型?synchronized和lock有什么区别?
多线程当中的阻塞队列 主要实现类有 ArrayBlockingQueue是一个基于数组结构的有界阻塞队列,此队列按FIFO原则对元素进行排序 LinkedBlockingQueue是一个基于链表结构的 ...
- 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题
调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...
- 多线程,线程类三种方式,线程调度,线程同步,死锁,线程间的通信,阻塞队列,wait和sleep区别?
重难点梳理 知识点梳理 学习目标 1.能够知道什么是进程什么是线程(进程和线程的概述,多进程和多线程的意义) 2.能够掌握线程常见API的使用 3.能够理解什么是线程安全问题 4.能够知道什么是锁 5 ...
随机推荐
- 扩展jQuery---选中指定索引的文本
<script type="text/javascript"> //1.扩展jQuery $.fn.selectRange = function (start, end ...
- ThinkPHP5.0中Request请求对象的使用和常用的操作
request的使用 第一种方法 在控制器头部添加request引用 然后在方法里调用 ‘instance’类 然后在调用方法: public function index($name='name') ...
- hibernate自动生成时报错问题
创建好了实体类和.hbm.xml文件,运行项目报上错: 实体类和xml文件中的字段要一致.(顺序和字段)
- DP设状态 : 状压与线
[NOIP2017]宝藏(状压) [AHOI2009]中国象棋(状压) [BZOJ1814] URAL1519 Formula 1(插头\(DP\)模板) 新链接 : Luogu5056 , dark ...
- 【算法笔记】B1007 素数对猜想
1007 素数对猜想 (20 分) 让我们定义dn为:dn=pn+1−pn,其中pi是第i个素数.显然有d1=1,且对于n>1有dn是偶数.“素数对猜想 ...
- 关于:“无法序列化会话状态。在“StateServer”或“SQLServer”模式下,...的问题
关于:“无法序列化会话状态.在“StateServer”或“SQLServer”模式下,...的问题 错误描述: 无法序列化会话状态.在“StateServer”或“SQLServer”模式下,ASP ...
- opacity 兼容 ie8
opacity: 0.6; filter: alpha(opacity=60);
- 【实战】简述一次挖XSS的经历
值守尤其是夜班真的是件痛苦的事情呀,献给还在值守岗位上奋斗的小伙伴们. 简单试了前面几个参数,发现c0-id这个参数值在响应包里有回显,截图如下: 把c0-id参数值改为xss,响应包内容也随之变化, ...
- git——合并分支
A将自己的本地代码提交到远程A分支,此时master主干上有B新提交的代码,如果此时A把自己的代码merge到主干,会有冲突,那怎么办? 1.A将自己的代码提交到自己的A分支 2.git fetch ...
- TOJ 1883 Domino Effect
Description Did you know that you can use domino bones for other things besides playing Dominoes? Ta ...