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小结的更多相关文章

  1. java 中的equals()小结

    转载自http://www.cnblogs.com/jackyrong/archive/2006/08/20/481994.html Java中的equals是十分重要的,和= =要区别开来,最近在看 ...

  2. java中的collection小结

    Collection 来源于Java.util包,是非常实用常用的数据结构!!!!!字面意思就是容器.具体的继承实现关系如下图,先整体有个印象,再依次介绍各个部分的方法,注意事项,以及应用场景.   ...

  3. JAVA中的字符串小结

    String字符串是只读的,不可变的 查看String类的源码,可以发现String类是被final关键字修饰的: 另外还可以看下String类源码中的其它方法实现,随便举个可以修改String值的方 ...

  4. JAVA中的枚举小结

    枚举 将一组有限集合创建为一种新的类型,集合里面的值可以作为程序组件使用: 枚举基本特性 以下代码是枚举的简单使用: 使用values方法返回enum实例的数组 使用ordinal方法返回每个enum ...

  5. JAVA中的注解小结

    以下内容参考java编程思想-4,jdk版本为jdk5.0,有点老-_-||| 什么是注解 JAVA SE5引入,也称元数据,可以直接添加到代码中,用来完整描述程序所需的信息,而这些信息是无法用Jav ...

  6. JAVA中this用法小结

    Java关键字this只能用于方法方法体内.当一个对象创建后,Java虚拟机(JVM)就会给这个对象分配一个引用自身的指针,这个指针的名字就是 this.因此,this只能在类中的非静态方法中使用,静 ...

  7. java中内部类使用小结

    内部类是指在一个外部类中再定义一个类,类名不需要和文件名相同 内部类可以是静态的,类的修饰符可以是private,default,protect,public修饰 ,而外部类只能是public 和 d ...

  8. 转:JAVA中this用法小结

    转:http://blog.sina.com.cn/s/blog_6a6badc90100t8hm.html#SinaEditor_Temp_FontName Java关键字this只能用于方法方法体 ...

  9. java中String类小结

    构建一个字符串 1.用字符串直接量: String message = new String("Welcome to java"); 2.用字符串直接量: String messa ...

随机推荐

  1. megalo -- 网易考拉小程序解决方案

    megalo 是基于 Vue 的小程序框架(没错,又是基于 Vue 的小程序框架),但是它不仅仅支持微信小程序,还支持支付宝小程序,同时还支持在开发时使用更多 Vue 的特性. 背景 对于用户而言,小 ...

  2. Spark1.0.0 history server 配置

    在执行Spark应用程序的时候,driver会提供一个webUI给出应用程序的执行信息.可是该webUI随着应用程序的完毕而关闭port,也就是说,Spark应用程序执行完后,将无法查看应用程序的历史 ...

  3. iOS设备定位服务开启判定

    应用CLLocationManager 的两个方法 [CLLocationManagerlocationServicesEnabled] 判断设备是否开启定位功能 [CLLocationManager ...

  4. com.android.support冲突的解决办法

    All com.android.support libraries must use the exact same version specification (mixing versions can ...

  5. js实现图片的等比例缩放

      js实现图片的等比例缩放 CreateTime--2018年3月6日14:04:18 Author:Marydon 1.代码展示 /** * 图片按宽高比例进行自动缩放 * @param ImgO ...

  6. 【BIEE】MDS-01377:无法从使用 JNDI 名称 “jdbc/mds/owsm” 配置的数据源获取数据库连接

    这是一次意外关机情况,BIEE环境是window server2008,但是一次意外情况,BIEE自动关机了,造成开启成功新启动BIEE产生如下错误: 错误产生后,倒腾了半天,并没发现什么问题,只是通 ...

  7. Drupal启动阶段之四:系统变量

    Drupal的系统变量是指保存在后台数据库variable表中的一些参数设置,透过variable_get()和variable_set()存取: 先看一看_drupal_bootstrap_vari ...

  8. 关于DevOps你必须知道的11件事

    转自:http://www.infoq.com/cn/articles/11devops 关于作者 Gene Kim在多个角色上屡获殊荣:CTO.研究者和作家.他曾是Tripwire的创始人并担任了1 ...

  9. linux ps查看进程命令详解

    http://linux.net527.cn/Linuxwendang/xitongguanliyuan/39094.htmlLinux操作系统PS命令详细解析 要对系统中进程进行监测控制,用 ps ...

  10. Could not create and/or set value back on to object .

    严重: Error building beanorg.springframework.beans.factory.UnsatisfiedDependencyException: Error creat ...