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 ...
随机推荐
- python读取中文
如何从文件中读取300个汉字? 看起来很简单,但很容易掉坑里了. 一开始我这么写: try: fd = codecs.open(os.path.join(settings.TEXT_CONTENT_D ...
- Short与Integer互转
int 是4字节, short 是2字节的, 如果将int(Integer)转成short(Short), 那么必须强制转换,否则会报编译异常. 但是, 当int(Integer)是一个final时, ...
- Storm---DirectGroup(直接分组)
以单词分割计数为例实现Storm的DirectGroup分组: 1.Spout实现 Spout是Storm数据源头,使用DirectGroup方式将Spout数据发送指定的Bolt,需注意: 1).S ...
- java中运算符与表达式
运算符是用来完成一个动作的特定语言的语法记号. –赋值运算符 –增减运算符 –算术运算符 –关系运算符 –逻辑运算符 -位运算符 运算符 Java 加 + 减 - 乘 * 除 / 取模 % 1.整数运 ...
- v - bind
1. 用于处理html标签的动态属性,即动态赋值(动态地绑定一个或多个特性,或一个组件 prop 到表达式) 2. 官网API <!DOCTYPE html> <html lang= ...
- selenium-Navigating
The first thing you’ll want to do with WebDriver is navigate to a link. The normal way to do this is ...
- input输入框禁止显示历史记录
有时我们在设计网页时不想让表单保存用户输入历史记录,比如一些隐私数据 <input name="test" type="text" id="te ...
- Hibernate 使用log4j输出日志
jar包不能少:F:\jars\slf4j-api-1.7.5.jar F:\strutsWsold\slf4j-1.7.5\slf4j-1.7.5\slf4j-log4j12-1.7.5.j ...
- js闭包避免内存泄漏 减少内存使用 避免对象无法回收注意事项
闭包 如果闭包的作用域中保存着一个 HTML 元素,则该元素无法被销毁.(下面代码来自高程) 闭包是 JavaScript 开发的一个关键方面:匿名函数可以访问父级作用域的变量. function a ...
- php_memcahed telnet远程操作方法
一.存储命令 存储命令的格式: <command name> <key> <flags> <exptime> <bytes> <dat ...