Java -- 使用阻塞队列(BlockingQueue)控制线程通信
BlockingQueeu接口是Queue的子接口,但是它的主要作用并不是作为容器,而是作为线程同步的工具。
特征:
当生产者线程试图向BlockingQueue中放入元素时,如果该队列已满,则该线程被阻塞;当消费者线程试图从BlockingQueue中取出元素时,如果该队列已空,则该线程被阻塞。
程序的两个线程通过交替从BlockingQueue中放入元素、取出元素,即可很好地控制线程的通信。
BlockingQueue提供如下两个支持阻塞的方法:
put(E e):尝试从BlockingQueue的头部取出元素,如果该队列的元素已满,则阻塞该线程。
take():尝试从BlockingQueue的头部取出元素,如果该队列的元素已空,则阻塞该线程。
BlockingQueue继承了Queue接口,当然也可以使用Queue接口的方法。这些方法归纳起来可分为3组:
- 在队列尾部插入元素。包括add(E e)、offer(E e)和put(E e)方法,当该队列已满时,这3个方法分别抛出异常、返回false、阻塞队列。
- 在队列头部删除并返回删除的元素。包括remove()、poll()和take()方法。当该队列已空时,这3个方法分别抛出异常、返回false、阻塞队列。
- 在队列头部取出但是不删除元素。包括element()和peek()方法,当队列已空时,这两个方法分别抛出异常、返回false。
BlockingQueue队列的5个实现类:
- ArrayBlockingQueue:基于数组实现的BlockingQueue队列
- LinkedBlockingQueue:基于链表实现的BlockingQueue队列
- PriorityBlockingQueue:.....
- SynchronousQueue:同步队列。对对垒的存、取操作必须交替进行
- DelayQueue:.....
具体代码示例:
package com.fuchenggang.blockingqueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; /**
* @ClassName: Producer
* @Description: 生产者
* @author fucg@kunyitech.com
* @date 2015年7月10日 下午4:08:03
*/
class Producer extends Thread {
private BlockingQueue<String> bq; public Producer(BlockingQueue<String> bq) {
this.bq = bq;
} @Override
public void run() {
String[] strArr = new String[]
{
"Java",
"Struts",
"Spring"
}; for (int i = 0; i < 999999999; i++) {
System.out.println(getName() + "生产者准备生产集合元素!"); try {
Thread.sleep(200);
//尝试放入元素,如果队列已满,则线程被阻塞
bq.put(strArr[i%3]);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println(getName() + "生产完成:" +bq);
}
}
} /**
* @ClassName: Consumer
* @Description: 消费者
* @author fucg@kunyitech.com
* @date 2015年7月10日 下午4:08:19
*/
class Consumer extends Thread{ private BlockingQueue<String> bq; public Consumer(BlockingQueue<String> bq) {
this.bq = bq;
} @Override
public void run() {
while (true) {
System.out.println(getName() + "消费者准备消费集合元素"); try {
Thread.sleep(200);
//尝试取出元素,如果队列已空,则线程被阻塞
bq.take();
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println(getName() + "消费完成:" + bq);
}
}
} /**
* @ClassName: BlockingQueueTest2
* @Description: 测试生产者线程和消费者线程的通信
* @author fucg@kunyitech.com
* @date 2015年7月10日 下午4:13:37
*/
public class BlockingQueueTest2 {
public static void main(String[] args) {
//创建一个容器为1的BlockingQueue
BlockingQueue<String> bq = new ArrayBlockingQueue<String>(1); //启动3个生产者线程
new Producer(bq).start();
new Producer(bq).start();
new Producer(bq).start(); //启动1个消费者线程
new Consumer(bq).start();
}
}
代码讲解:
程序启动了3个生产者线程向BolckingQueue集合放入元素,启动了1个消费者线程从BlockingQueue集合中取出元素。本程序的BlockingQueue集合容量为1,因此3个生产者线程无法连续放入元素,必须等待消费者线程取出一个元素后,3个生产者线程之一才能放入一个元素。
运行结果:
Java -- 使用阻塞队列(BlockingQueue)控制线程通信的更多相关文章
- java多线程-阻塞队列BlockingQueue
大纲 BlockingQueue接口 ArrayBlockingQueue 一.BlockingQueue接口 public interface BlockingQueue<E> exte ...
- Java---Condition控制线程通信
java中控制线程通信的方法有:1.传统的方式:利用synchronized关键字来保证同步,结合wait(),notify(),notifyAll()控制线程通信.不灵活. 2.利用Conditio ...
- Java并发编程-阻塞队列(BlockingQueue)的实现原理
背景:总结JUC下面的阻塞队列的实现,很方便写生产者消费者模式. 常用操作方法 常用的实现类 ArrayBlockingQueue DelayQueue LinkedBlockingQueue Pri ...
- Java并发(十八):阻塞队列BlockingQueue
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列. 这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用. 阻塞队列常用于生产 ...
- spring线程池ThreadPoolTaskExecutor与阻塞队列BlockingQueue
一: ThreadPoolTaskExecutor是一个spring的线程池技术,查看代码可以看到这样一个字段: private ThreadPoolExecutor threadPoolExecut ...
- Java并发指南11:解读 Java 阻塞队列 BlockingQueue
解读 Java 并发队列 BlockingQueue 转自:https://javadoop.com/post/java-concurrent-queue 最近得空,想写篇文章好好说说 java 线程 ...
- Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例
Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...
- Java集合--阻塞队列及各种实现的解析
阻塞队列(Blocking Queue) 一.队列的定义 说的阻塞队列,就先了解下什么是队列,队列也是一种特殊的线性表结构,在线性表的基础上加了一条限制:那就是一端入队列,一端出队列,且需要遵循FIF ...
- Java多线程 阻塞队列和并发集合
转载:大关的博客 Java多线程 阻塞队列和并发集合 本章主要探讨在多线程程序中与集合相关的内容.在多线程程序中,如果使用普通集合往往会造成数据错误,甚至造成程序崩溃.Java为多线程专门提供了特有的 ...
- Condition控制线程通信
Condition控制线程通信 一.前言 java.util.concurrent.locks.Condition 接口描述了可能会与锁有关联的条件变量.这些变量在用法上与使用Object.wait ...
随机推荐
- js对数值型数组排序错误
今天对一个js的数值数组排序,结果发现好像排后的像是对字符数组排的序,后来一查才发现 a = [33,1000]; a.sort(); 结果:1000 33 无论类型,sort方法会调用每个数组项的t ...
- 如何用纯 CSS 创作单元素点阵 loader
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览.https://codepen.io/comehope/pen/YvBvBr 可交互视频 此 ...
- VCF和GVCF格式说明
注意:本文的内容主要来自于GATK官网的讲解,所以vcf也是GATK产生的,用其他caller,比如varscan2产生的vcf文件的内容注释可能不一致. 参考:https://gatkforums. ...
- 20145321 《Java程序设计》第10周学习总结
20145321 <Java程序设计>第10周学习总结 教材学习内容总结 网络编程:网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输. IP地址:为了能够方便的识别网络上 ...
- Jackson 框架JSON、XML、List、Map直接相互转换
博客分类: json 参考:http://www.cnblogs.com/hoojo/archive/2011/04/22/2024628.html 在其基础上做了稍微调整 详情见附件 jacks ...
- CentOS7系统安装配置samba服务
# 查询是否已经安装了Samba rpm -qi samba # 安装 yum -y install samba samba-client samba-common # 添加新用户 useradd s ...
- Mysql uploader File
前几天和哥们做一次渗透测试,内网情况.防护相当严格. 内网不允许访问DMZ,DMZ不允许访问内网,除了服务端口,比如80,3306. 经过长时间的分析,就发现本机连接了内网的一个MYQL,发现WEB开 ...
- 使用IP spoofer 功能
有个问题请教:使用IP spoofer 功能后,很多vuser都会挂掉,这个怎么解决呢? LR
- 正确使用iOS常量(const)、enum以及宏(#define)
前言:本文主要梳理iOS中如何使用常量.enum.宏,以及各自的使用场景. 重要的事情首先说:在iOS开发中请尽量多使用const.enum来代替宏定义(#define):随着项目工程的逐渐增大,过多 ...
- 新浪云连接数据库php
一般数据库连接$con = mysql_connect("localhost", "root", ""); 而新浪云共享数据库 <?p ...