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. 关于http协议session和cookie的理解

    http是无状态协议,不能够记录访问者的身份, 为了解决这一问题服务器端设置了session 浏览器端设置了cookie 这种机制 当浏览器第一次访问服务器的时候,服务器会判断是否有cookie的存在 ...

  2. mysql有关问题之:the security settings could not be applied to

    mysql问题之:the security settings could not be applied to 转自:http://www.myexception.cn/mysql/503556.htm ...

  3. Hibernate从入门到上手(纯java project、Maven版本hibernate)

    Hibernate(orm框架)(开放源代码的对象关系映射框架) Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一 ...

  4. java小游戏代码

    一. 需求分析 曾几何时,游戏是海洛因的代名词,让人与玩物丧志联系在一起.一度遭到社会反感和家长抵制.可是.随着互联网的发展,和游戏潜在优点被发现.游戏的价值開始逐渐被社会认可,人们開始接受.认识和了 ...

  5. 病毒木马查杀实战第015篇:U盘病毒之脱壳研究

    前言 因为我们的终于目标是编写出针对于这次的U盘病毒的专杀工具.而通过上次的分析我们知道,病毒有可能在不同的计算机中会以不同的名称进行显示.假设真是如此,那么就有必要在此分析出病毒的命名规律等特征,然 ...

  6. Android File类 根据官方文档理解

    File有四个构造函数        public File(File dir,String name)             参数为File和String,File制定构造的新的File对象的路径 ...

  7. Game Center Achievements and Leaderboards part 1 <转>

    原地址:http://blog.sina.com.cn/s/blog_6b3661a901013xb0.html This is the first part of a step-by-step tu ...

  8. 算法笔记_080:蓝桥杯练习 队列操作(Java)

    目录 1 问题描述 2 解决方案 1 问题描述 问题描述 队列操作题.根据输入的操作命令,操作队列(1)入队.(2)出队并输出.(3)计算队中元素个数并输出. 输入格式 第一行一个数字N. 下面N行, ...

  9. Visual studio之C# 调用系统软键盘(外部"osk.exe")

    背景 App需要调用系统软键盘输入数据,自己去实现软键盘有些复杂,现在又是急需,没时间去研究实现软键盘,所以只能调用系统软键盘. 正文 需要添加命名空间, using System.Diagnosti ...

  10. JBoss类加载机制 ClassLoadingConfiguration

    http://sylven.iteye.com/blog/577063 类仓库优先级从低到高 1.classpath.lib目录 2.由已部署的应用程序的所有类./server/{server_nam ...