在前面我们提到了阻塞队列,也用过了LinkedBolckingQueue队列了,在这里,我们主要对 ArrayBlockingQueue,PriorityBlockingQueue,DelayQueue,SynchronousQueue,LinkedTransferQueue,LinkedBlockingDeque的使用方法和应用场景做一个补充。

  • ArrayBlockingQueue:基于数组实现的阻塞队列,先进先出队列,有界队列。在创建时必须制定容量大小。并可以指定公平性与非公平性,默认情况下是非公平的,即不保证等待时间最长的队列最优先能够访问队列。
  • LinkedBlockingQueue:基于链表实现的阻塞队列,先进先出队列,有界队列。在创建时如果不指定容量大小,则默认大小为Integer.MAX_VALUE。
  • PriorityBlockingQueue:按照元素的优先级对元素进行排序,按照优先级顺序出队。并且该阻塞队列为无界阻塞队列,即容量没有上限(源码中它没有容器满的信号标志)。
  • DelayQueue:基于PriorityQueue的延时阻塞队列,无界队列。DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素。因为DelayQueue是一个无界队列,所以往队列中插入数据的操作永远不会被阻塞,而只有获取数据的操作才会被阻塞。
  • SynchronousQueue:一个不存储元素的阻塞队列。
  • LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
  • LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。

(1) ArrayBlockingQueue示例:

import java.util.concurrent.ArrayBlockingQueue;public class ArrayBolckingQueueDemo {static ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(2);public static void main(String[] args) {ArrayBolckingQueueDemo demo = new ArrayBolckingQueueDemo();Product p = demo.new Product();Eat e = demo.new Eat();Thread t1 = new Thread(e);Thread t2 = new Thread(p);t2.start();t1.start();}class Product implements Runnable {@Overridepublic void run() {while (true) {try {queue.put("apple");System.out.println(Thread.currentThread().getName() + "put  queue:" + queue.toString());Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}class Eat implements Runnable {@Overridepublic void run() {while (true) {try {queue.take();System.out.println(Thread.currentThread().getName() + "eat queue:" + queue.toString());Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}}}}
}

  结果:

(2)LinkedBlockingQueue示例这里不介绍,大家可以看我前面的博客“Java多线程_阻塞队列”
(3)PriorityBlockingQueue示例:

import java.util.concurrent.PriorityBlockingQueue;public class PriorityBlockingQueueDemo {public static void main(String[] args) {PriorityBlockingQueue<People> queue = new PriorityBlockingQueue<>();PriorityBlockingQueueDemo demo = new PriorityBlockingQueueDemo();queue.put(demo.new People("tom", 19));queue.put(demo.new People("jack", 18));queue.put(demo.new People("tony", 21));while (!queue.isEmpty()) {try {System.out.println(queue.take().toString());} catch (InterruptedException e) {e.printStackTrace();}}}class People implements Comparable<People> {private String name;private Integer age;public People(String name, Integer age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic int compareTo(People o) {if (this.age > o.age) {return 1;} else {return -1;}}@Overridepublic String toString() {// TODO Auto-generated method stubreturn "name:" + name + " age:" + age;}}
}

结果:

(4)DelayQueue应用场景:
1) 关闭空闲连接。服务器中,有很多客户端的连接,空闲一段时间之后需要关闭。
2) 缓存。缓存中的对象,超过了空闲时间,需要从缓存中移出。
3) 任务超时处理。

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;public class DelayQueueDemo {public static void main(String[] args) {DelayQueueDemo demo = new DelayQueueDemo();DelayQueue<People> queue = new DelayQueue<>();queue.put(demo.new People("tom", 4000 + System.currentTimeMillis()));queue.put(demo.new People("jack", 1000 + System.currentTimeMillis()));queue.put(demo.new People("tony", 6000 + System.currentTimeMillis()));while (!queue.isEmpty()) {try {System.out.println(queue.take().toString());} catch (InterruptedException e) {e.printStackTrace();}}}class People implements Delayed {private String name;private long time;// 截止时间public People(String name, long time) {super();this.name = name;this.time = time;}public String getName() {return name;}public void setName(String name) {this.name = name;}public long getTime() {return time;}public void setTime(long time) {this.time = time;}@Overridepublic String toString() {return "name:" + name + "  time:" + time;}@Overridepublic int compareTo(Delayed o) {People p = (People) o;if (time - p.time > 0) {return 1;} else {return -1;}}@Overridepublic long getDelay(TimeUnit unit) {return time - System.currentTimeMillis();}}
}

结果:

(5)SynchronousQueue示例:
注意点:每个 put 必须等待一个 take,反之亦然。

import java.util.Random;
import java.util.concurrent.SynchronousQueue;public class SynchronousQueueDemo {static SynchronousQueue<Integer> queue = new SynchronousQueue<>();public static void main(String[] args) {SynchronousQueueDemo demo = new SynchronousQueueDemo();Productor p = demo.new Productor();Consumer c = demo.new Consumer();Thread t1 = new Thread(p);Thread t2 = new Thread(c);t1.start();t2.start();}class Productor implements Runnable {@Overridepublic void run() {while (true) {int data = new Random().nextInt(1000);System.out.println("put " + data);try {queue.put(data);Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}class Consumer implements Runnable {@Overridepublic void run() {while (true) {try {System.out.println("take " + queue.take());Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}
}

结果:

(6)LinkedBlockingDeque和LinkedTransferQueue
这两个队列都是后期才产生的队列。
LinkedTransferQueue是一个由链表结构组成的无界阻塞队列。他与LinkedBolckingQueue最大的不同就是这个队列是无界的,而LinkedBolckingQueue是有界的,用法大致相同,这里不作介绍。
LinkedBlockingDeque最大的不同就是它是一个双向的基于链表的阻塞队列。该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除),用法差别也不大,不作介绍。

转载于:https://www.cnblogs.com/ericz2j/p/10300953.html

Java多线程_JUC包下的阻塞队列相关推荐

  1. Java多线程之线程并发库阻塞队列的应用

    ArrayBlockingQueue(jdk中已经提供 就在那个condition类说明里的可阻塞示例程序的下面就说明了) 注意三个添加方法的区别->查API文档 拿插入来说 一个会抛异常 一个 ...

  2. Java基础教程:多线程基础(3)——阻塞队列

    Java基础教程:多线程基础(3)--阻塞队列 快速开始 引入问题 生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据. 模 ...

  3. java.util.regex包下的Pattern和Matcher详解(正则匹配)

    java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现(建议在阅读本文时,打开java API文档,当介绍到哪个方法时,查看java API中的方法说明,效果 ...

  4. java不同的包下相同的类名的问题与解决办法

    java不同的包下相同的类名的问题与解决办法 参考文章: (1)java不同的包下相同的类名的问题与解决办法 (2)https://www.cnblogs.com/yanggb/p/10650256. ...

  5. java下载sun包下的源码

    为什么要重下sun包? sun包下的类,都是.class文件.例如:sun.net.www.protocol.http.HttpURLConnection的源码,竟然是.class.原因是JDK自带的 ...

  6. java反射获取包下所有的类

    引三方包 <dependency><groupId>org.reflections</groupId><artifactId>reflections&l ...

  7. 111 多线程JUC包下代码分析

    2019独角兽企业重金招聘Python工程师标准>>> Java多线程系列目录(共43篇) AtomicLongFieldUpdater:通过反射+CAS实现对传入对象的指定long ...

  8. java concurrent 框架,java.util.concurrent 包下的 Synchronizer 框架

    看完书 java concurrency in practice 当然是想找点啥好玩的东东玩玩. 当看到了Doug Lee 的论文 << The java.util.concurrent ...

  9. java.util 常见_Java基础知识-java.util.concurrent包下常见类的使用

    一,Condition 一个场景,两个线程数数,同时启动两个线程,线程A数1.2.3,然后线程B数4.5.6,最后线程A数7.8.9,程序结束,这涉及到线程之间的通信. public classCon ...

最新文章

  1. Android零基础入门第25节:最简单最常用的LinearLayout线性布局
  2. vba给服务器发送消息,使用VBA实现发邮件功能
  3. 小李飞刀:python请你轻轻轻点虐
  4. 内存管理 初始化(七)kmem_cache_init_late 初始化slab分配器(下)
  5. SAP Spartacus使用了ngrx library
  6. 滤波电容的选择(调试中)
  7. C++:画数组元素直方图
  8. 【数据库】数据库基础
  9. 【乐理入门】——音符与五线谱(1)
  10. 【高考往期真题】—— 2022高考数学全国 I 卷参考答案
  11. 【鸟哥的Linux私房菜】第十二章、学习shell脚本
  12. VS2017编译SQLite3生成.lib
  13. 直击本质:聊聊小程序的前世今生
  14. 示波器探头校准-调节补偿电容
  15. java课程表_用Java做个课程表(5)
  16. Ubuntu安装已下载了.deb文件的软件
  17. js点击元素之外的地方隐藏该元素
  18. Webpack配置区分开发环境和生产环境
  19. 什么是特斯拉?他和爱迪生相爱相杀。
  20. 单机百万连接调优和Netty应用级别调优

热门文章

  1. 当我们安装使用时,会出现eclipse启动不了,出现“Java was started but returned exit code=13......”的问题...
  2. 毫秒级百万数据分页存储过程(mssql)
  3. Socket编程Http下载的简单实现
  4. ORACLE PL/SQ入门
  5. ajax成功后没有执行函数,ajax不执行回调函数
  6. 如何运行网页html,如何在网页中运行html代码
  7. java GoF 的 23 种设计模式的分类和功能
  8. [Java] 蓝桥杯ALGO-103 算法训练 完数
  9. [Java] 蓝桥杯BASIC-28 基础练习 Huffuman树
  10. 1020. 月饼 (25)-PAT乙级真题