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 ...
随机推荐
- JS 为页面对象新增自定义方法
有些时候html的一些控件是自动生成的,我们无法修改,但是我们能改改页面所调用的一些公用的JS. 这样的话我们可以自定义JS事件. function sel_OnClick() { //dosth.. ...
- 3C - Youmu
(ans & arr[j]) == ans 保证高位已有值不失效. ((ans[j] >> (i - 1)) & 1) == 1 当前位为1,cnt++, cnt > ...
- A printf format reference page (cheat sheet)
Summary: This page is a printf formatting cheat sheet. I originally created this cheat sheet for my ...
- ssm框架搭建出现的异常:The import org.springframework cannot be resolved
1.检查是否有这个包;是否在maven依赖中添加了spring-context.,检查后我有这个包,而且在仓库中找到了 2.怀疑没有下完整,将其删除又导了一遍,还是报错. 3.后来重启了一遍eclip ...
- Week 3: Structured Types 5. Tuples and Lists Exercise: odd tuples
Exercise: odd tuples 5/5 points (graded) ESTIMATED TIME TO COMPLETE: 5 minutes Write a procedure cal ...
- CSS2.1
学而时习之,不亦说乎! --<论语> CSS:cascading style sheet(层叠样式表) 作用:描述页面的样式. 书 ...
- PIE SDK元素位置和显示样式的修改
1功能简介 在数据的处理中会出现根据需求进行元素的位置和显示样式的修改,使元素的形状,空间位置得到改变,下面将介绍基于PIE SDK的元素位置和显示样式的修改. 2功能实现说明 2.1.1 实现思路及 ...
- Python学习 day04
一.list list可以存放各种类型的数据,与java中list类差不多,比如li = ['keith', 1, True, [1, 2, 3], {name: 'tangtang', age: 1 ...
- FileSearch.java
!=fileList.size()) { ]) { fileOutputStream.write(bytes; i < files.length; i++) {// 将其中的文件夹遍历出来,并调 ...
- 牛客网Java刷题知识点之数组、链表、哈希表、 红黑二叉树
不多说,直接上干货! 首先来说一个非常形象的例子,来说明下数组和链表. 上体育课的时候,老师说:你们站一队,每个人记住自己是第几个,我喊到几,那个人就举手,这就是数组. 老师说,你们每个人记住自己前面 ...