阻塞队列 (BlockingQueue)是Java util.concurrent包下重要的数据结构,BlockingQueue提供了线程安全的队列访问方式:当阻塞队列进行插入数据时,如果队列已满,线程将会阻塞等待直到队列非满;从阻塞队列取
阻塞队列 (BlockingQueue)是Java util.concurrent包下重要的数据结构,BlockingQueue提供了线程安全的队列访问方式:当阻塞队列进行插入数据时,如果队列已满,线程将会阻塞等待直到队列非满;从阻塞队列取数据时,如果队列已空,线程将会阻塞等待直到队列非空。并发包下很多高级同步类的实现都是基于BlockingQueue实现的。
BlockingQueue 的操作方法
BlockingQueue 具有 4 组不同的方法用于插入、移除以及对队列中的元素进行检查。如果请求的操作不能得到立即执行的话,每个方法的表现也不同。这些方法如下:
四组不同的行为方式解释:
无法向一个 BlockingQueue 中插入 null。如果你试图插入 null,BlockingQueue 将会抛出一个 NullPointerException。
可以访问到 BlockingQueue 中的所有元素,而不仅仅是开始和结束的元素。比如说,你将一个对象放入队列之中以等待处理,但你的应用想要将其取消掉。那么你可以调用诸如 remove(o) 方法来将队列之中的特定对象进行移除。但是这么干效率并不高(译者注:基于队列的数据结构,获取除开始或结束位置的其他对象的效率不会太高),因此你尽量不要用这一类的方法,除非你确实不得不那么做。
BlockingQueue 的实现类
BlockingQueue 是个接口,你需要使用它的实现之一来使用BlockingQueue,Java.util.concurrent包下具有以下 BlockingQueue 接口的实现类:
使用例子:
阻塞队列的最长使用的例子就是生产者消费者模式,也是各种实现生产者消费者模式方式中首选的方式。使用者不用关心什么阻塞生产,什么时候阻塞消费,使用非常方便,代码如下:
package MyThread;import java.util.Random;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.TimeUnit;public class BlockingQueueTest { //生产者 public static class Producer implements Runnable{ private final BlockingQueue<Integer> blockingQueue; private volatile boolean flag; private Random random; public Producer(BlockingQueue<Integer> blockingQueue) { this.blockingQueue = blockingQueue; flag=false; random=new Random(); } public void run() { while(!flag){ int info=random.nextInt(100); try { blockingQueue.put(info); System.out.println(Thread.currentThread().getName()+" produce "+info); Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void shutDown(){ flag=true; } } //消费者 public static class Consumer implements Runnable{ private final BlockingQueue<Integer> blockingQueue; private volatile boolean flag; public Consumer(BlockingQueue<Integer> blockingQueue) { this.blockingQueue = blockingQueue; } public void run() { while(!flag){ int info; try { info = blockingQueue.take(); System.out.println(Thread.currentThread().getName()+" consumer "+info); Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void shutDown(){ flag=true; } } public static void main(String[] args){ BlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<Integer>(10); Producer producer=new Producer(blockingQueue); Consumer consumer=new Consumer(blockingQueue); //创建5个生产者,5个消费者 for(int i=0;i<10;i++){ if(i<5){ new Thread(producer,"producer"+i).start(); }else{ new Thread(consumer,"consumer"+(i-5)).start(); } } try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } producer.shutDown(); consumer.shutDown(); }}
--结束END--
本文标题: 详解Java阻塞队列(BlockingQueue)的实现原理
本文链接: https://www.lsjlt.com/news/225160.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-05-14
2024-05-14
2024-05-14
2024-05-14
2024-05-14
2024-05-14
2024-05-14
2024-05-14
2024-05-14
2024-05-14
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0