在前面我们提到了阻塞队列,也用过了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包下的阻塞队列的更多相关文章

  1. Java多线程高并发学习笔记——阻塞队列

    在探讨可重入锁之后,接下来学习阻塞队列,这边篇文章也是断断续续的写了很久,因为最近开始学ssm框架,准备做一个自己的小网站,后续可能更新自己写网站的技术分享. 请尊重作者劳动成果,转载请标明原文链接: ...

  2. Java多线程之并发包,并发队列

    目录 1 并发包 1.1同步容器类 1.1.1Vector与ArrayList区别 1.1.2HasTable与HasMap 1.1.3 synchronizedMap 1.1.4 Concurren ...

  3. Java并发编程(十)阻塞队列

    使用非阻塞队列的时候有一个很大问题就是:它不会对当前线程产生阻塞,那么在面对类似消费者-生产者的模型时,就必须额外地实现同步策略以及线程间唤醒策略,这个实现起来就非常麻烦.但是有了阻塞队列就不一样了, ...

  4. Java并发(7):阻塞队列

    在前面我们接触的队列都是非阻塞队列,比如PriorityQueue.LinkedList(LinkedList是双向链表,它实现了Dequeue接口). 使用非阻塞队列的时候有一个很大问题就是:它不会 ...

  5. Java中常用的七个阻塞队列介绍第一篇

    Java中常用的七个阻塞队列介绍第一篇 在上一篇我们对Java中的队列分类做了简单的介绍.本文咱们主要来聊聊阻塞队列中的七个常用子类.这七个阻塞队列的学习步骤:先看源码,分析完源码之后,我们再来对每个 ...

  6. java.util.regex包下的Pattern类和Matcher类的使用总结

    一.介绍 Java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现1.Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不 ...

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

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

  8. Java语言Lang包下常用的工具类介绍_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 无论你在开发哪中 Java 应用程序,都免不了要写很多工具类/工具函数.你可知道,有很多现成的工具类可用,并且代码质量都 ...

  9. Java中常用的七个阻塞队列第二篇DelayQueue源码介绍

    Java中常用的七个阻塞队列第二篇DelayQueue源码介绍 通过前面两篇文章,我们对队列有了了解及已经认识了常用阻塞队列中的三个了.本篇我们继续介绍剩下的几个队列. 本文主要内容:通过源码学习De ...

随机推荐

  1. consul与springcloud整合

    1. 服务提供者注册进consul 1.1新建支付服务module cloud-providerconsul-payment8006 1.2 pom.xml <?xml version=&quo ...

  2. 学习MySQL这一篇就够了

    MySQL 第一章 数据库概述 1.1.数据库的好处 将数据持久化到本地 提供结构化查询功能 1.2.数据库的常见概念 DB:数据库,存储数据的仓库 DBS:数据库管理系统,又称为数据库软件或者数据库 ...

  3. 给定两个列表,转换为 DataFrame 类型

    import pandas as pd def get_data(): q1 = [] q2 = [] p1 = input("list 1:") p2 = input(" ...

  4. 5-Pandas之常用的描述性统计函数、汇总函数

    一.常用的描述性统计函数  函数 作用 函数 作用 count 非缺失样本的数量 sum 求和 mean 均值 mad 平均绝对偏差(Mean absolute deviation) median 中 ...

  5. MOSFET 的 I / V 特性曲线

    https://www.cnblogs.com/yeungchie/ MOSFET 线性区(三极管区,\(V_{DS} \leq V_{GS} - V_{TH}\)) \[I_{D} = \mu_{n ...

  6. 6.15 省选模拟赛 老魔杖 博弈论 SG函数

    这道题确实没有一个很好的解决办法 唯一的正解可能就是打表找规律 或者 直接猜结论了吧. 尽管如此 在此也给最终结论一个完整的证明. 对于70分 容易发现状态数量不大 可以进行暴力dp求SG函数. 原本 ...

  7. bzoj 5206 [Jsoi2017]原力

    LINK:原力 一张无向图 这道题统计三元环的价值和.有重边但是无自环. 我曾经写过三元环计数 这个和那个题差不太多. 不过有很多额外操作 对于重边问题 我们把所有颜色相同的重边缩在一起 这样的话我们 ...

  8. springboot2.1.x版本报错总结

    我使用的是springboot  2.1.7.RELEASE  springcloud  Greenwich.SR2 boot和cloud对应的版本号不能搞混,对应版本请参考https://sprin ...

  9. js的栈内存和堆内存

    栈内存和堆内存在了解一门语言底层数据结构上,挺重要的,做了个总结 JS中的栈内存堆内存 JS的内存空间分为栈(stack).堆(heap).池(一般也会归类为栈中). 其中栈存放变量,堆存放复杂对象, ...

  10. Qt 之 Graphics View Framework 简介

    Graphics View Framework 交互式 2D 图形的 Graphics View 框架概述.自 Qt4.2 中引入了 Graphics View,以取代其前身 QCanvas.Grap ...