Java中的BlockingQueue小结
BlockingQueue是java.util.concurrent下的主要用来控制线程同步的工具。
主要的方法是:put、take一对阻塞存取;add、poll一对非阻塞存取。
插入:
1) add(anObject):把anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则抛出异常,不好
2) offer(anObject):表示如果可能的话,将anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false.
3) put(anObject):把anObject加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续, 有阻塞, 放不进去就等待
读取:
4) poll(time):取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null; 取不到返回null
5) take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到Blocking有新的对象被加入为止; 阻塞, 取不到就一直等
其他:
int remainingCapacity();返回队列剩余的容量,在队列插入和获取的时候,不要瞎搞,数据可能不准, 不能保证数据的准确性
boolean remove(Object o); 从队列移除元素,如果存在,即移除一个或者更多,队列改变了,返回true
public boolean contains(Object o); 查看队列是否存在这个元素,存在返回true
int drainTo(Collection<? super E> c); //移除此队列中所有可用的元素,并将它们添加到给定 collection中。取出放到集合中
int drainTo(Collection<? super E> c, int maxElements); 和上面方法的区别在于,指定了移动的数量; 取出指定个数放到集合
BlockingQueue有四个具体的实现类,常用的两种实现类为:
1、ArrayBlockingQueue:一个由数组支持的有界阻塞队列,规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小.其所含的对象是以FIFO(先入先出)顺序排序的。
2、LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定.其所含的对象是以FIFO(先入先出)顺序排序的。
LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。
LinkedBlockingQueue和ArrayBlockingQueue区别:
LinkedBlockingQueue和ArrayBlockingQueue比较起来,它们背后所用的数据结构不一样,导致LinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue,但在线程数量很大时其性能的可预见性低于ArrayBlockingQueue。
下面写一个生产者消费者的例子:
TestBlockingQueueProducer.java:
package cn.itcast_02_blockingqueue.main; import java.util.Random;
import java.util.concurrent.BlockingQueue; public class TestBlockingQueueProducer implements Runnable {
BlockingQueue<String> queue;
Random random = new Random(); public TestBlockingQueueProducer(BlockingQueue<String> queue) {
this.queue = queue;
} @Override
public void run() { for (int i = 0; i < 10; i++) {
try {
Thread.sleep(random.nextInt(10));
String task = Thread.currentThread().getName() + " made a product " + i; System.out.println(task);
queue.put(task);
} catch (InterruptedException e) { e.printStackTrace();
} } } }
TestBlockingQueueConsumer.java:
package cn.itcast_02_blockingqueue.main; import java.util.Random;
import java.util.concurrent.BlockingQueue; public class TestBlockingQueueConsumer implements Runnable{
BlockingQueue<String> queue;
Random random = new Random(); public TestBlockingQueueConsumer(BlockingQueue<String> queue){
this.queue = queue;
}
@Override
public void run() {
try {
Thread.sleep(random.nextInt(10));
System.out.println(Thread.currentThread().getName()+ " trying...");
String temp = queue.take();//如果队列为空,会阻塞当前线程
System.out.println(Thread.currentThread().getName() + " get a job " +temp);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
TestBlockingQueue.java:
package cn.itcast_02_blockingqueue.main; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; public class TestBlockingQueue { public static void main(String[] args) {
BlockingQueue<String> queue = new LinkedBlockingQueue<String>(2);
// BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
// 不设置的话,LinkedBlockingQueue默认大小为Integer.MAX_VALUE
// BlockingQueue<String> queue = new ArrayBlockingQueue<String>(2);
TestBlockingQueueConsumer consumer = new TestBlockingQueueConsumer(queue);
TestBlockingQueueProducer producer = new TestBlockingQueueProducer(queue);
for (int i = 0; i < 5; i++) {
new Thread(producer, "Producer" + (i + 1)).start();
}
for (int i = 0; i < 5; i++) {
new Thread(consumer, "Consumer" + (i + 1)).start();
} //new Thread(producer, "Producer" + (5)).start();
}
}
运行结果:
Consumer2 trying...
Producer3 made a product 0
Consumer2 get a job Producer3 made a product 0
Producer3 made a product 1
Producer4 made a product 0
Consumer5 trying...
Consumer5 get a job Producer3 made a product 1
Producer4 made a product 1
Producer4 made a product 2
Consumer3 trying...
Producer2 made a product 0
Consumer3 get a job Producer4 made a product 0
Consumer1 trying...
Producer5 made a product 0
Consumer1 get a job Producer4 made a product 1
Producer3 made a product 2
Producer1 made a product 0
Consumer4 trying...
Consumer4 get a job Producer4 made a product 2
Producer2 made a product 1
Producer4 made a product 3
Producer5 made a product 1
可以看到,只有先生产出来,才能消费,否则阻塞等待。
Java中的BlockingQueue小结的更多相关文章
- java 中的equals()小结
转载自http://www.cnblogs.com/jackyrong/archive/2006/08/20/481994.html Java中的equals是十分重要的,和= =要区别开来,最近在看 ...
- java中的collection小结
Collection 来源于Java.util包,是非常实用常用的数据结构!!!!!字面意思就是容器.具体的继承实现关系如下图,先整体有个印象,再依次介绍各个部分的方法,注意事项,以及应用场景. ...
- JAVA中的字符串小结
String字符串是只读的,不可变的 查看String类的源码,可以发现String类是被final关键字修饰的: 另外还可以看下String类源码中的其它方法实现,随便举个可以修改String值的方 ...
- JAVA中的枚举小结
枚举 将一组有限集合创建为一种新的类型,集合里面的值可以作为程序组件使用: 枚举基本特性 以下代码是枚举的简单使用: 使用values方法返回enum实例的数组 使用ordinal方法返回每个enum ...
- JAVA中的注解小结
以下内容参考java编程思想-4,jdk版本为jdk5.0,有点老-_-||| 什么是注解 JAVA SE5引入,也称元数据,可以直接添加到代码中,用来完整描述程序所需的信息,而这些信息是无法用Jav ...
- JAVA中this用法小结
Java关键字this只能用于方法方法体内.当一个对象创建后,Java虚拟机(JVM)就会给这个对象分配一个引用自身的指针,这个指针的名字就是 this.因此,this只能在类中的非静态方法中使用,静 ...
- java中内部类使用小结
内部类是指在一个外部类中再定义一个类,类名不需要和文件名相同 内部类可以是静态的,类的修饰符可以是private,default,protect,public修饰 ,而外部类只能是public 和 d ...
- 转:JAVA中this用法小结
转:http://blog.sina.com.cn/s/blog_6a6badc90100t8hm.html#SinaEditor_Temp_FontName Java关键字this只能用于方法方法体 ...
- java中String类小结
构建一个字符串 1.用字符串直接量: String message = new String("Welcome to java"); 2.用字符串直接量: String messa ...
随机推荐
- IDEA java开发 Restful 风格的WebService
官网:https://www.jetbrains.com/help/idea/restful-webservices.html 1.在IntelliJ中创建新项目,选择Java Enterprise ...
- Maven Web项目配置Mybatis出现SqlSessionFactory错误的解决方案
一.错误现象 严重: Context initialization failed org.springframework.beans.factory.BeanCreationException: Er ...
- iOS 程序从开发完到上 AppStore 那点事儿
收录待用,修改转载已取得腾讯云授权 一.账号体系 想要进行iOS开发,除了必备一台装有Mac OS X/Xcode的Mac开发机(iMac or MacBook)之外,还必须要有苹果开发者账号,只有拥 ...
- Linux远程执行Windows机器任务
Linux远程执行Windows机器任务 近期测试人员提出需求需要在Linux下调用Windows系统下的cmd的命令完成自动构建和测试并生成测试报告. 环境: Windows Server2 ...
- 转: Android Studio你不知道的调试技巧
http://tianweishu.com/2015/12/21/android-studio-debug-tips-you-may-not-know/
- 通过NAT实例实现外部访问AWS的ElastiCache资源
ElastiCache作为AWS的内存缓存组建可以说做的一点也不友好了, 你可以通过ElastiCache创建redis,memcache的实例,却不能被外部访问. 背景 人傻钱多的客户总有人傻钱多的 ...
- PHPMailer_v5.1 使用[转]
<?php /* * email 报警,主要检查服务器数据库是否还能正常连接 */ require("../common/config.php"); include(&quo ...
- Js、JQuery脚本兼容
1.获取属性值 IE:$("#xxx").prop("title"); chrome:$("#xxx").attr("title& ...
- 【大盛】全网首发HTC One/M7 最新本地化TrickDroid9.0/固件升级/永久root/高级,快速设置/稳定,流畅经典ROM
了解更多请关注:点击打开链接 ROM版本 HTC One/M7_TrickDroid9.0.0 ROM作者 雪狼团队-大盛 http://weibo.com/DaShengdd Android版本 ...
- 如何查看LoadRunner虚拟用户(vuser)类型
查看vuser类型LoadRunner提供了多种Vuser技术,通过这些技术可以在使用不同类型的客户端/服务器体系结构时生成服务器负载.每种Vuser技术都适合于特定体系结构并产生特定的Vuser类型 ...