在前面我们提到了阻塞队列,也用过了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. python学习笔记1 -- 函数式编程之高阶函数 filter

    filter 函数用于过滤序列,与map 和reduce函数类似,作为高阶函数,他们也是同样的使用方法,filter(参数1, 参数2),参数1是一个函数,而参数2是一个序列. filter的作用是根 ...

  2. 枚举-称硬币POJ1013

    #include <iostream> #include<string.h> using namespace std; char Lleft[][]; char Lright[ ...

  3. 挖地雷dp c++

    // // Created by Arc on 2020/4/27. // /*题文: * 在一个地图上有n个地窖 * ,每个地窖中没有一定数量的地雷, * 同时给出地窖之间连接的路径, * 并规定路 ...

  4. Linux系统的基本操作

    20200727 Linux目录结构 基本介绍 Linux的文件系统是采用层级式的树状结构,在此结构中的最上层是/根目录 tip1:在Linux世界里,一切皆是文件 示例 /bin: bin是Bina ...

  5. dfs树

    dfs树是解决图中带环的利器. 前天CF的F题就是dfs树,但是当时我没有认真思考 觉着找到一个环过于困难 当时没有想到 也没理解dfs树的意义. 对于一张无向图求出一个dfs树 这个树有两种边 树边 ...

  6. Nginx使用中遇到的问题记录

    问题一.关于空格 nginx配置对空格十分敏感,在关键字和符号的前后,一定记得有空格(或换行).一个典型的场景是 if { } 语句,大括号前后要有空格,否则可能出现非预期行为. 问题二.关于serv ...

  7. ORACLE不完成恢复ORA-00392,ORA-00312,ORA-00349

    背景: 进行测试库不完全恢复,log_file_name_convert没调整好.rac-asm至单实例-文件系统,recover完成后,mount状态的database  执行 alter data ...

  8. 浅谈Mybatis持久化框架在Spring、SSM、SpringBoot整合的演进及简化过程

    前言 最近开始了SpringBoot相关知识的学习,作为为目前比较流行.用的比较广的Spring框架,是每一个Java学习者及从业者都会接触到一个知识点.作为Spring框架项目,肯定少不了与数据库持 ...

  9. 【NOIP2016】组合数问题 题解(组合数学+递推)

    题目链接 题目大意:给定$n,m,k$,求满足$k|C_i^j$的$C_i^j$的个数.$(0\leq i\leq n,1\leq j\leq \min(i,m))$. --------------- ...

  10. OpenCV开发笔记(六十九):红胖子8分钟带你使用传统方法识别已知物体(图文并茂+浅显易懂+程序源码)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...