Java多线程_JUC包下的阻塞队列
在前面我们提到了阻塞队列,也用过了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 { @Override
public 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 { @Override
public 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;
} @Override
public int compareTo(People o) {
if (this.age > o.age) {
return 1;
} else {
return -1;
}
} @Override
public String toString() {
// TODO Auto-generated method stub
return "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;
} @Override
public String toString() {
return "name:" + name + " time:" + time;
} @Override
public int compareTo(Delayed o) {
People p = (People) o;
if (time - p.time > 0) {
return 1;
} else {
return -1;
}
} @Override
public 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 { @Override
public 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 { @Override
public 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两种操作方式,即可以从队列的头和尾同时操作(插入/删除),用法差别也不大,不作介绍。
Java多线程_JUC包下的阻塞队列的更多相关文章
- Java多线程高并发学习笔记——阻塞队列
在探讨可重入锁之后,接下来学习阻塞队列,这边篇文章也是断断续续的写了很久,因为最近开始学ssm框架,准备做一个自己的小网站,后续可能更新自己写网站的技术分享. 请尊重作者劳动成果,转载请标明原文链接: ...
- Java多线程之并发包,并发队列
目录 1 并发包 1.1同步容器类 1.1.1Vector与ArrayList区别 1.1.2HasTable与HasMap 1.1.3 synchronizedMap 1.1.4 Concurren ...
- Java并发编程(十)阻塞队列
使用非阻塞队列的时候有一个很大问题就是:它不会对当前线程产生阻塞,那么在面对类似消费者-生产者的模型时,就必须额外地实现同步策略以及线程间唤醒策略,这个实现起来就非常麻烦.但是有了阻塞队列就不一样了, ...
- Java并发(7):阻塞队列
在前面我们接触的队列都是非阻塞队列,比如PriorityQueue.LinkedList(LinkedList是双向链表,它实现了Dequeue接口). 使用非阻塞队列的时候有一个很大问题就是:它不会 ...
- Java中常用的七个阻塞队列介绍第一篇
Java中常用的七个阻塞队列介绍第一篇 在上一篇我们对Java中的队列分类做了简单的介绍.本文咱们主要来聊聊阻塞队列中的七个常用子类.这七个阻塞队列的学习步骤:先看源码,分析完源码之后,我们再来对每个 ...
- java.util.regex包下的Pattern类和Matcher类的使用总结
一.介绍 Java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现1.Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不 ...
- java.util.regex包下的Pattern和Matcher详解(正则匹配)
java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现(建议在阅读本文时,打开java API文档,当介绍到哪个方法时,查看java API中的方法说明,效果 ...
- Java语言Lang包下常用的工具类介绍_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 无论你在开发哪中 Java 应用程序,都免不了要写很多工具类/工具函数.你可知道,有很多现成的工具类可用,并且代码质量都 ...
- Java中常用的七个阻塞队列第二篇DelayQueue源码介绍
Java中常用的七个阻塞队列第二篇DelayQueue源码介绍 通过前面两篇文章,我们对队列有了了解及已经认识了常用阻塞队列中的三个了.本篇我们继续介绍剩下的几个队列. 本文主要内容:通过源码学习De ...
随机推荐
- 手牵手,从零学习Vue源码 系列二(变化侦测篇)
系列文章: 手牵手,从零学习Vue源码 系列一(前言-目录篇) 手牵手,从零学习Vue源码 系列二(变化侦测篇) 陆续更新中... 预计八月中旬更新完毕. 1 概述 Vue最大的特点之一就是数据驱动视 ...
- matplotlib基础汇总_02
设置plot的风格和样式 点和线的样式 颜色 参数color或c 五种定义颜色值的方式 别名 color='r' 合法的HTML颜色名 color = 'red' HTML十六进制字符串 color ...
- Django学习路16_获取学生所在的班级名
在 urls.py 中先导入getgrades from django.conf.urls import url from app5 import views urlpatterns = [ url( ...
- PHP gmstrftime() 函数
------------恢复内容开始------------ 实例 根据区域设置格式化 GMT/UTC 日期和时间: <?phpecho(gmstrftime("%B %d %Y, % ...
- Qt数据库 QSqlTableModel实例操作(转)
本文介绍的是Qt数据库 QSqlTableModel实例操作,详细操作请先来看内容.与上篇内容衔接着,不顾本文也有关于上篇内容的链接. Qt数据库 QSqlTableModel实例操作是本文所介绍的内 ...
- 一个简单的CPP处理框架
好久没有在csdn上写过东西了,这么多年,一方面是工作忙,下班到家也没有开过电脑了,要陪小孩玩: 下面分享一段代码,是用CPP做的一个简单的消息(协议)处理框架: 是通过成员函数指针+map来实现的: ...
- Axios源码分析
Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中. 文档地址:https://github.com/axios/axios axios理解和使用 1.请求配置 { // ...
- 未来云原生世界的“领头羊”:容器批量计算项目Volcano 1.0版本发布
在刚刚结束的CLOUD NATIVE+ OPEN SOURCE Virtual Summit China 2020上,由华为云云原生团队主导的容器批量计算项目Volcano正式发布1.0版本,标志着V ...
- java_字节流、字符流的使用方法
字节流 字节输出流[OutputStream] java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地.它定义了字节输出流的基本共性功能方法. p ...
- 十多位全球技术专家,为你献上近十个小时的.Net微服务介绍
.Net Conf: Focus on Microservices 是 .Net Conf 社区在 2020 年 7 月 30 日举办的线上分享活动.整个活动视频长达近 10 个小时.今天我们来看看都 ...