java-线程-使用阻塞队列(BlockingQueue)控制线程通信

BlockingQueue是一个接口,也是Queue的子接口。BlockingQueue具有一个特征:当生产者线程试图向BlockingQueue中放入元素时,如果该队列已满,则线程被阻塞;但消费者线程试图从BlockingQueue中取出元素时,如果队列已空,则该线程阻塞。

程序的两个线程通过交替向BlockingQueue中放入元素、取出元素,即可很好地控制线程的通信。

BlockingQueue提供如下两个支持阻塞的方法:

put(E e):尝试把Eu元素放如BlockingQueue中,如果该队列的元素已满,则阻塞该线程。

take():尝试从BlockingQueue的头部取出元素,如果该队列的元素已空,则阻塞该线程。

BlockingQueue继承了Queue接口,当然也可以使用Queue接口中的方法,这些方法归纳起来可以分为如下三组:

1、在队列尾部插入元素,包括add(E e)、offer(E e)、put(E e)方法,当该队列已满时,这三个方法分别会抛出异常、返回false、阻塞队列。

2、在队列头部删除并返回删除的元素。包括remove()、poll()、和take()方法,当该队列已空时,这三个方法分别会抛出异常、返回false、阻塞队列。

3、在队列头部取出但不删除元素。包括element()和peek()方法,当队列已空时,这两个方法分别抛出异常、返回false。

BlockingQueue接口包含如下5个实现类:

1、ArrayBlockingQueue :基于数组实现的BlockingQueue队列。

2、LinkedBlockingQueue:基于链表实现的BlockingQueue队列。

3、PriorityBlockingQueue:它并不是保准的阻塞队列,该队列调用remove()、poll()、take()等方法提取出元素时,并不是取出队列中存在时间最长的元素,而是队列中最小的元素。它判断元素的大小即可根据元素(实现Comparable接口)的本身大小来自然排序,也可使用Comparator进行定制排序。

4、SynchronousQueue:同步队列。对该队列的存、取操作必须交替进行。

5、DelayQueue:它是一个特殊的BlockingQueue,底层基于PriorityBlockingQueue实现,不过,DelayQueue要求集合元素都实现Delay接口(该接口里只有一个long getDelay()方法),DelayQueue根据集合元素的getDalay()方法的返回值进行排序。

 1 import java.util.concurrent.ArrayBlockingQueue;
 2 import java.util.concurrent.BlockingQueue;
 3 public class BlockingQueueTest{
 4     public static void main(String[] args)throws Exception{
 5         //创建一个容量为1的BlockingQueue
 6
 7         BlockingQueue<String> b=new ArrayBlockingQueue<>(1);
 8         //启动3个生产者线程
 9         new Producer(b).start();
10         new Producer(b).start();
11         new Producer(b).start();
12         //启动一个消费者线程
13         new Consumer(b).start();
14
15     }
16 }
17 class Producer extends Thread{
18     private BlockingQueue<String> b;
19
20     public Producer(BlockingQueue<String> b){
21         this.b=b;
22
23     }
24     public synchronized void run(){
25         String [] str=new String[]{
26             "java",
27             "struts",
28             "Spring"
29         };
30         for(int i=0;i<9999999;i++){
31             System.out.println(getName()+"生产者准备生产集合元素!");
32             try{
33
34                 b.put(str[i%3]);
35                 sleep(1000);
36                 //尝试放入元素,如果队列已满,则线程被阻塞
37
38             }catch(Exception e){System.out.println(e);}
39             System.out.println(getName()+"生产完成:"+b);
40         }
41
42     }
43 }
44 class Consumer extends Thread{
45     private BlockingQueue<String> b;
46     public Consumer(BlockingQueue<String> b){
47         this.b=b;
48     }
49     public  synchronized  void run(){
50
51         while(true){
52             System.out.println(getName()+"消费者准备消费集合元素!");
53             try{
54                 sleep(1000);
55                 //尝试取出元素,如果队列已空,则线程被阻塞
56                 b.take();
57             }catch(Exception e){System.out.println(e);}
58             System.out.println(getName()+"消费完:"+b);
59         }
60
61     }
62 }
时间: 2024-10-26 06:35:28

java-线程-使用阻塞队列(BlockingQueue)控制线程通信的相关文章

java中的阻塞队列BlockingQueue

一.概述 位于java.util.concurrent下,声明:public interface BlockingQueue<E> extends Queue<E> 支持两个附加操作的 Queue,这两个操作是:获取元素时等待队列变为非空,以及存储元素时等待空间变得可用. BlockingQueue 方法以四种形式出现,对于不能立即满足但可能在将来某一时刻可以满足的操作,这四种形式的处理方式不同:第一种是抛出一个异常,第二种是返回一个特殊值(null 或 false,具体取决于操作

JAVA线程池ThreadPoolExecutor与阻塞队列BlockingQueue .

从Java5开始,Java提供了自己的线程池.每次只执行指定数量的线程,java.util.concurrent.ThreadPoolExecutor 就是这样的线程池.以下是我的学习过程. 首先是构造函数签名如下: [java] view plain copy print ? public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<

spring线程池ThreadPoolTaskExecutor与阻塞队列BlockingQueue

一: ThreadPoolTaskExecutor是一个spring的线程池技术,查看代码可以看到这样一个字段: private ThreadPoolExecutor threadPoolExecutor; 可以发现,spring的  ThreadPoolTaskExecutor是使用的jdk中的java.util.concurrent.ThreadPoolExecutor进行实现, 直接看代码: @Override protected ExecutorService initializeExe

线程池ThreadPoolExecutor与阻塞队列BlockingQueue应用

作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.线程池介绍 JDK5.0以上: java.util.concurrent.ThreadPoolExecutor 构造函数签名: public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, Reje

阻塞队列模型和线程池

阻塞队列模型介绍 阻塞队列模型和线程池息息相关,因此本篇博客先介绍阻塞队列的相关知识.如下图所示: 首先我们来说,什么是Queue,然后在谈什么是BlockingQueue. 那么什么是Queue呢?一句话,就是一端进,另一端出,这样就形成了First In , First Out,即先进先出.而BlockingQueue只不过是在Queue的基础上进行了2个附加操作而已:如果Queue空,那么Out线程阻塞,如果Queue满,那么In线程阻塞. 理解了上面的Queue/BlockingQueu

Java多线程与并发库高级应用之阻塞队列BlockingQueue

JDK1.5提供了阻塞队列接口BlockingQueue,它是一个有界阻塞队列.BlockingQueue实现是线程安全的,可以安全地与多个生产者和多个使用者一起使用. 使用时用其实现类 ArrayBlockingQueue,它一个由数组支持的有界阻塞队列.此队列按 FIFO(先进先出)原则对元素进行排序.队列的头部 是在队列中存在时间最长的元素.队列的尾部是在队列中存在时间最短的元素.新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素. 这是一个典型的"有界缓存区",固定

深入剖析java并发之阻塞队列LinkedBlockingQueue与ArrayBlockingQueue

关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入理解Java并发之synchronized实现原理 Java并发编程-无锁CAS与Unsafe类及其并发包Atomic 深入理解Java内存模型(JMM)及volatile关键字 剖析基于并发AQS的重入锁(ReetrantLock)及其Condition实现原理 剖析基于并发AQS的共

JAVA并发之阻塞队列浅析

背景 因为在工作中经常会用到阻塞队列,有的时候还要根据业务场景获取重写阻塞队列中的方法,所以学习一下阻塞队列的实现原理还是很有必要的.(PS:不深入了解的话,很容易使用出错,造成没有技术深度的样子) 阻塞队列是什么? 要想了解阻塞队列,先了解一下队列是啥,简单的说队列就是一种先进先出的数据结构.(具体的内容去数据结构里学习一下)所以阻塞队列就是一种可阻塞的队列.和普通的队列的不同就体现在 ”阻塞“两个字上.阻塞是啥意思? 百度看一下 在软件工程里阻塞一般指的是阻塞调用,即调用结果返回之前,当前线

多线程编程学习六(Java 中的阻塞队列).

介绍 阻塞队列(BlockingQueue)是指当队列满时,队列会阻塞插入元素的线程,直到队列不满:当队列空时,队列会阻塞获得元素的线程,直到队列变非空.阻塞队列就是生产者用来存放元素.消费者用来获取元素的容器. 当线程 插入/获取 动作由于队列 满/空 阻塞后,队列也提供了一些机制去处理,或抛出异常,或返回特殊值,或者线程一直等待... 方法/处理方式 抛出异常 返回特殊值 一直阻塞 超时退出 插入方法 add(e) offer(e) put(e) offer(e, timeout, unit

Java中的阻塞队列

1. 什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列.这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用.阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程.阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素. 阻塞队列提供了四种处理方法: 方法\处理方式 抛出异常 返回特殊值 一直阻塞 超时退出 插入方法 add(e) offer(e) put