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 ...
随机推荐
- Python学习【第五篇】:面向对象及相关
面向对象基础 基础内容介绍详见一下两篇博文: 面向对象初级篇 面向对象进阶篇 其他相关 一.isinstance(obj, cls) 检查是否obj是否是类 cls 的对象 1 2 3 4 5 6 c ...
- PHP将数据库数据批量生成word文档
<?php class word{ function start(){ ob_start(); echo '<html x ...
- JUC包下CyclicBarrier学习笔记
CyclicBarrier,一个同步辅助类,在API中是这么介绍的: 它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这 ...
- Qt 学习之路 2(50):自定义可编辑模型
Home / Qt 学习之路 2 / Qt 学习之路 2(50):自定义可编辑模型 Qt 学习之路 2(50):自定义可编辑模型 豆子 2013年5月13日 Qt 学习之路 2 13条评论 上一章我们 ...
- 011 Android TabLayout+ViewPager实现顶部滑动效果(多个页面)
1.TabLayout介绍 TabLayout提供了一个水平的布局用来展示Tabs,很多应用都有这样的设计,典型的有网易新闻,简书,知乎等.TabLayout就可以很好的完成这一职责,首先TabLay ...
- tornado 06 数据库—ORM—SQLAlchemy——基本内容及操作
tornado 06 数据库—ORM—SQLAlchemy——基本内容及操作 一. ORM #在服务器后台,数据是要储存在数据库的,但是如果项目在开发和部署的时候,是使用的不同的数据库,该怎么办?是不 ...
- 113th LeetCode Weekly Contest Reveal Cards In Increasing Order
In a deck of cards, every card has a unique integer. You can order the deck in any order you want. ...
- aoj0121
一.题意:类似于华容道,输入是8个数字,输入虽然是一行,但实际是以两行的方式操作的.0表示空位,别的相邻数字可移动到该位置上.求最少移动步骤得到指定的状态. 二.思路:这题可以用BFS来解决.因为在每 ...
- (转)Openldap相关精品文章
1.运维咖啡吧 https://mp.weixin.qq.com/s__biz=MzU5MDY1MzcyOQ==&mid=2247483754&idx=1&sn=9f20d45 ...
- linux对于zombie的处理
@(Linux基础)[僵尸进程处理] 今天在服务器上推送项目的时候,突然发现很卡.就用top查看了一下,果然此事不简单啊. top - 10:39:16 up 20 days, 23:11, 2 us ...