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

来源:互联网 发布:sp 知乎 编辑:程序博客网 时间:2024/06/06 19:35

当生产者试图向BlockingQueue中放入元素时,如果该队列已满,则该线程被阻塞;当消费者试图从BlockingQueue取出元素时,如果该队列为空,则该线程被阻塞。


package bloc;import java.util.concurrent.*;public class BlockingQueueTest{public static void main(String[] args)throws Exception{// 定义一个长度为2的阻塞队列BlockingQueue<String> bq = new ArrayBlockingQueue<>(2);bq.put("Java"); // 与bq.add("Java"、bq.offer("Java")相同bq.put("Java"); // 与bq.add("Java"、bq.offer("Java")相同bq.put("Java"); // ① 阻塞线程。}}

package bloc;import java.util.concurrent.*;class Producer extends Thread{private BlockingQueue<String> bq;public Producer(BlockingQueue<String> bq){this.bq = bq;}public void run(){String[] strArr = new String[]{"Java","Struts","Spring"};for (int i = 0 ; i < 999999999 ; i++ ){System.out.println(getName() + "生产者准备生产集合元素!");try{Thread.sleep(200);// 尝试放入元素,如果队列已满,线程被阻塞bq.put(strArr[i % 3]);}catch (Exception ex){ex.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 (Exception ex){ex.printStackTrace();}System.out.println(getName() + "消费完成:" + bq);}}}public class BlockingQueueTest2{public static void main(String[] args){// 创建一个容量为1的BlockingQueueBlockingQueue<String> bq = new ArrayBlockingQueue<>(1);// 启动3条生产者线程new Producer(bq).start();new Producer(bq).start();new Producer(bq).start();// 启动一条消费者线程new Consumer(bq).start();}}

ArrayBlockingQueue

   一个由数组支持的有限阻塞队列(其大小在创建的时候就被确定,并且不能在修改)。此队列里存储的元素顺序是FIFO(first-in-first-out),是一个很标准的普通队列,也是我们最常使用到的阻塞队列。其头部的元素是在队列带的时间最长,尾部元素在队列中呆的时间最短,新来的元素是插在尾部的,而当队列获取元素时是从头部获取的。如果试图将一个元素put到一个full状态的队列,这个操作就会被阻塞,直到队列有空位置。如果从一个empty队列获取新的元素同样也会被阻塞,知道有元素可获取。


DelayQueue

    此队列是一个无界限的队列,只有当他的元素在队列中超过规定时间了他才可以被取出来,其头部是超期时间最长的元素,尾部就是超期最短(或还未过期)的元素。如果还没有过期的元素,那么就不存在头部了,将直接返当回null,他的队列调用了元素的getDelay()方法返回的值小于或等于0就表示过期了。

    这个队列不是所有的元素都可以放进去的,必须是实现了Delayed接口的类对象才可以放进去,否则就会报类型转换异常,


LinkedBlockingQueue

    是一个基于连接节点的任意大小容量的队列,这个队列的顺序是FIFO,其头部是存入队列最早的元素,尾部是存入队列最晚的元素,每次都是讲元素插入尾部,从头部取出元素。LinkedBlockingQueue:比ArrayBlockingQueue有更大的吞吐量,但是在并发的情况下其性能是不可预测的。

http://blog.csdn.net/u012481172/article/details/50469690  参考链接

阅读全文
0 0
原创粉丝点击