java并发编程工具类JUC之ArrayBlockingQueue
java blockingqueue接口java.util.concurrent.blockingqueue表示一个可以存取元素,并且线程安全的队列。换句话说,当多线程同时从 javablockingqueue中插入元素、获取元素的时候,不会导致任何并发问题(元素被插入多次、处理多次等问题)。
从java blockingqueue可以引申出一个概念:阻塞队列,是指队列本身可以阻塞线程向队列里面插入元素,或者阻塞线程从队列里面获取元素。比如:当一个线程尝试去从一个空队列里面获取元素的时候,这个线程将被阻塞直到队列内元素数量不再为空。当然,线程是否会被阻塞取决于你调用什么方法从blockingqueue获取元素,有的方法会阻塞线程,有的方法会抛出异常等等,下文我们会详细介绍。
类arrayblockingqueue
是blockingqueue
接口的实现类,它是有界的阻塞队列,内部使用数组存储队列元素。这里的“有界”是指存储容量存在上限,不能无限存储元素。在同一时间内存储容量存在着一个上限值,这个上限制在初始实例化的时候指定,之后便不能修改了。
arrayblockingqueue
内部采用fifo (first in, first out)先进先出的方法实现队列数据的存取,队首的元素是在队列中保存时间最长的元素对象,队尾的元素是在队列中保存时间最短的元素对象。
下面的代码说明如何初始化一个arrayblockingqueue
,并向其中添加一个对象:
blockingqueue queue = new arrayblockingqueue(1024); queue.put("1"); //向队列中添加元素 object object = queue.take(); //从队列中取出元素
blockingqueue
可以通过泛型来限定队列中存储数据的类型,下面的代码以string为泛型,表示该队列只能存储string类型。
blockingqueue<string> queue = new arrayblockingqueue<string>(1024); queue.put("1"); string string = queue.take();
实现一个生产消费的实例
在前面的文章中我们曾经讲过:blockingqueue经常被用于生产消费的缓冲队列。下面我们就使用arrayblockingqueue
来真正的实现一个生产消费的例子。
类blockingqueueexample
开启两个独立线程,一个是producer
生产者线程,负责向队列中添加数据;另一个是consumer
消费者线程,负责从队列中取出数据进行处理。
public class blockingqueueexample { public static void main(string[] args) throws exception { //使用arrayblockingqueue初始化一个blockingqueue,指定容量的上限为1024 blockingqueue queue = new arrayblockingqueue(1024); producer producer = new producer(queue); //生产者 consumer consumer = new consumer(queue); //消费者 new thread(producer).start(); //开启生产者线程 new thread(consumer).start(); //开启消费者线程 thread.sleep(4000); } }
类producer
为生产者,每隔10秒钟使用put()
方法向队列中放入一个对象,放入三次。在这10秒的间隔内,队列数据被消费者取走之后将导致消费者线程阻塞。
public class producer implements runnable{ protected blockingqueue queue = null; public producer(blockingqueue queue) { this.queue = queue; } public void run() { try { queue.put("1"); thread.sleep(10000); queue.put("2"); thread.sleep(10000); queue.put("3"); } catch (interruptedexception e) { e.printstacktrace(); } } }
下面的代码是消费者类consumer
,它从队列中获取待处理的元素对象,并调用system.out
将其打印出来。
public class consumer implements runnable{ protected blockingqueue queue = null; public consumer(blockingqueue queue) { this.queue = queue; } public void run() { try { system.out.println(queue.take()); system.out.println(queue.take()); system.out.println(queue.take()); } catch (interruptedexception e) { e.printstacktrace(); } } }
上面的代码打印结果是每隔10秒打印一次,因为其中take()
方法在队列内没有元素可以取到的时候,会阻塞当前的消费者线程,让其处于等待状态,这个方法我们在上一节介绍blockingqueue
的时候就已经进行过说明。
以上就是java并发编程工具类juc之arrayblockingqueue的详细内容,更多关于java并发编程工具类arrayblockingqueue的资料请关注其它相关文章!
推荐阅读
-
荐 Java——数据库编程JDBC之数据库连接池技术(C3P0与Druid,提供了Druid的工具类)
-
JAVA并发编程(三):同步的辅助类之闭锁(CountDownLatch)与循环屏障(CyclicBarrier)
-
Java多线程并发编程中并发容器第二篇之List的并发类讲解
-
Java并发编程7–并发工具之Condition
-
并发编程(八)—— Java 并发队列 BlockingQueue 实现之 ArrayBlockingQueue 源码分析
-
Java并发编程之工具类Semaphore的使用
-
java并发编程工具类JUC之ArrayBlockingQueue
-
荐 Java——数据库编程JDBC之数据库连接池技术(C3P0与Druid,提供了Druid的工具类)
-
Java并发编程的艺术:(8) Java 中的并发工具类
-
Java中的原子操作类 / 并发工具类(Java并发编程的艺术笔记)