使用阻塞队列(BlockingQueue)控制线程通信:
2016-09-21 14:05
585 查看
使用阻塞队列(BlockingQueue)控制线程通信:
(1)Java5提供了一个BlockingQueue接口,虽然BlockingQueue也是Queue的子接口,但它的主要用途并不是作为容器,而是作为线程同步的工具类。BlockingQueue具有一个特征:当生产者线程试图向BlockingQueue中放入元素时,如果该队列已满,则该线程被阻塞;当消费者试图从BlockingQueue中取出元素时,如果队列已空,则该线程被阻塞
(2)程序的两个线程通过交替向BlockingQueue中放入元素、取出元素,即可很好的控制线程通信。
(3)BlockingQueue提供如下两个支持阻塞的办法:
put(E e) 尝试把E元素放入BlockingQueue中,如果该队列元素已满,则阻塞该线程。
take() 尝试从BlockingQueue的头部取出元素,如果该队列的元素已空,则阻塞该线程。
(4)BlockingQueue继承了Queue接口,当然也可以使用Queue中的方法:
*在队列尾部插入元素。包括add(E e) offer(E e) put( E e)
*在队列头部删除并且返回删除的元素。包括 remove() poll() take().
*在队列头部取出但不删除元素。包括element()和peek()方法
(5)BlockingQueue包含以下5个实现类:
ArrayBlockingQueue:基于数组实现的BlockingQueue队列
LinkedBlockingQueue:基于链表实现的BlockingQueue队列
PriorityBlockingQueue:
SynchronousQueue:同步队列,该队列的存取操作必须交替进行。
DelayQueue:
以ArrayBlockingQueue为例介绍阻塞队列的用法。
运行结果:
Thread-0生产者准备生产集合元素
Thread-1生产者准备生产集合元素
Threa
b5cf
d-2生产者准备生产集合元素
Thread-3消费者准备消费集合元素
Thread-0生产完成[java]
Thread-0生产者准备生产集合元素
Thread-1生产完成[java]
Thread-1生产者准备生产集合元素
Thread-3消费完成:[java]
Thread-3消费者准备消费集合元素
Thread-2生产完成[java]
Thread-2生产者准备生产集合元素
Thread-3消费完成:[java]
Thread-3消费者准备消费集合元素
Thread-3消费完成:[c++]
Thread-0生产完成[c++]
Thread-0生产者准备生产集合元素
Thread-3消费者准备消费集合元素
Thread-1生产完成[c++]
Thread-3消费完成:[c++]
Thread-3消费者准备消费集合元素
Thread-1生产者准备生产集合元素
上面程序启动了三个生产者线程向BlockingQueue集合放入元素,启动了一个消费者线程从BlockingQueue中取出元素。本程序的集合容量为1.因此三个生产者无法连续放入元素,必须等待消费者取出一个元素之后,生产者之一才能放入一个元素。
(1)Java5提供了一个BlockingQueue接口,虽然BlockingQueue也是Queue的子接口,但它的主要用途并不是作为容器,而是作为线程同步的工具类。BlockingQueue具有一个特征:当生产者线程试图向BlockingQueue中放入元素时,如果该队列已满,则该线程被阻塞;当消费者试图从BlockingQueue中取出元素时,如果队列已空,则该线程被阻塞
(2)程序的两个线程通过交替向BlockingQueue中放入元素、取出元素,即可很好的控制线程通信。
(3)BlockingQueue提供如下两个支持阻塞的办法:
put(E e) 尝试把E元素放入BlockingQueue中,如果该队列元素已满,则阻塞该线程。
take() 尝试从BlockingQueue的头部取出元素,如果该队列的元素已空,则阻塞该线程。
(4)BlockingQueue继承了Queue接口,当然也可以使用Queue中的方法:
*在队列尾部插入元素。包括add(E e) offer(E e) put( E e)
*在队列头部删除并且返回删除的元素。包括 remove() poll() take().
*在队列头部取出但不删除元素。包括element()和peek()方法
(5)BlockingQueue包含以下5个实现类:
ArrayBlockingQueue:基于数组实现的BlockingQueue队列
LinkedBlockingQueue:基于链表实现的BlockingQueue队列
PriorityBlockingQueue:
SynchronousQueue:同步队列,该队列的存取操作必须交替进行。
DelayQueue:
以ArrayBlockingQueue为例介绍阻塞队列的用法。
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class BlockingQueueTest{ public static void main(String[] args) throws Exception { //定义一个长度为2的阻塞队列 BlockingQueue<String> bq=new ArrayBlockingQueue<>(2); bq.put("java"); bq.put("c++"); bq.put("java");//阻塞线程 } }
利用BlockingQueue来实现线程通信: import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; class Producer extends Thread{ private BlockingQueue<String> bq; public Producer(BlockingQueue<String> bq){ this.bq=bq; } public void run(){ String [] strArr= new String []{"java","c++","china"}; for (int i = 0; i < 999999999; i++) { System.out.println(getName()+"生产者准备生产集合元素"); try { Thread.sleep(200); //尝试放入元素,如果队列已满,则线程被阻塞 bq.put(strArr [ i % 3]); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(getName()+"生产完成"+bq); } } } class Consumer extends Thread{ private BlockingQueue<String> bq; public Consumer(BlockingQueue<String> bq){ this.bq=bq; } public void run(){ while(true){ System.out.println(getName()+"消费者准备消费集合元素"); try { Thread.sleep(200); //尝试取出元素,如果队列已空,则线程被阻塞 bq.take(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(getName()+"消费完成:"+bq); } } } public class BlockingQueueTest2 { public static void main(String[] args) { //创建一个容量为1的BlockingQueue BlockingQueue<String> bq = new ArrayBlockingQueue<>(1); //启动三个生产者线程 new Producer(bq).start(); new Producer(bq).start(); new Producer(bq).start(); //启动一个消费者线程 new Consumer(bq).start(); } }
运行结果:
Thread-0生产者准备生产集合元素
Thread-1生产者准备生产集合元素
Threa
b5cf
d-2生产者准备生产集合元素
Thread-3消费者准备消费集合元素
Thread-0生产完成[java]
Thread-0生产者准备生产集合元素
Thread-1生产完成[java]
Thread-1生产者准备生产集合元素
Thread-3消费完成:[java]
Thread-3消费者准备消费集合元素
Thread-2生产完成[java]
Thread-2生产者准备生产集合元素
Thread-3消费完成:[java]
Thread-3消费者准备消费集合元素
Thread-3消费完成:[c++]
Thread-0生产完成[c++]
Thread-0生产者准备生产集合元素
Thread-3消费者准备消费集合元素
Thread-1生产完成[c++]
Thread-3消费完成:[c++]
Thread-3消费者准备消费集合元素
Thread-1生产者准备生产集合元素
上面程序启动了三个生产者线程向BlockingQueue集合放入元素,启动了一个消费者线程从BlockingQueue中取出元素。本程序的集合容量为1.因此三个生产者无法连续放入元素,必须等待消费者取出一个元素之后,生产者之一才能放入一个元素。
相关文章推荐
- 线程通信---使用阻塞队列(BlockingQueue)控制线程通信
- java使用阻塞队列(BlockingQueue)来控制线程通信
- Java -- 使用阻塞队列(BlockingQueue)控制线程通信
- 学习java多线程的笔记3-使用BlockingQueue阻塞队列来模拟两个线程之间的通信
- 线程通信(3) - 使用阻塞队列(Blocking Queue)控制线程通信
- Java中使用阻塞队列控制线程集实例
- Java阻塞队列线程集控制的实现
- 使用队列和线程对现有asp.net动态页处理进行资源控制
- 使用Condition控制线程通信
- iOS多线程学习---控制线程通信及线程使用的总结
- BlockingQueue-线程的阻塞队列
- (13)多线程与并发库之java5阻塞队列(BlockingQueue)的应用----子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着再回到主线程循环100次,如此循环50次
- Java线程(篇外篇):阻塞队列BlockingQueue
- Java线程(十三):BlockingQueue-线程的阻塞队列
- 使用 线程池,控制线程 , 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待:
- Java线程外篇:阻塞队列BlockingQueue
- Java阻塞队列线程集控制的实现
- 使用队列和线程对现有asp.net动态页处理进行资源控制
- 12-使用java5条件阻塞condition实现线程间通信-实现线程间通信方式(2)
- 使用Windows消息队列处理线程之间通信