在前面我们提到了阻塞队列,也用过了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. 扯扯Java中的锁

    前言 又过去了一个周末,最近陆陆续续的看了<并发编程的艺术>一书,对锁有不少感悟,这次就聊聊Java中的锁事.本文纯粹是漫谈,想到哪说到哪,但准确性肯定会保证,倘若有不正确之处,还请交流指 ...

  2. jmeter单接口和多接口测试

    @@@@@@@@@@@@@@@ # 路漫漫其修远 最近接触到了多接口串联,接口串联的技术会在其他帖子有说明,其核心技术点就是通过正则表达式和变量来实现接口的关联.目前为止呢笔者用到的地方还只有一个,就 ...

  3. PHP 循环 - While 循环

    PHP 循环 - While 循环 循环执行代码块指定的次数,或者当指定的条件为真时循环执行代码块. PHP 循环 在您编写代码时,您经常需要让相同的代码块一次又一次地重复运行.我们可以在代码中使用循 ...

  4. HTML 布局 - 使用<div> 元素

    网站布局 大多数网站会把内容安排到多个列中(就像杂志或报纸那样).高佣联盟 www.cgewang.com 大多数网站可以使用 <div> 或者 <table> 元素来创建多列 ...

  5. AC自动机&后缀自动机

    理解的不够深 故只能以此来加深理解 .我这个人就是蠢没办法 学长讲的题全程蒙蔽.可能我字符串就是菜吧,哦不我这个人就是菜吧. AC自动机的名字 AC 取自一个大牛 而自动机就比较有讲究了 不是寻常的东 ...

  6. linux的服务管理(centos6和Centos7)和网络管理(网卡配置),计划服务cron

    服务和网络 管理 init  ifcfg ens33 1.服务: Linux系统中提供的功能,统称为服务,如:at服务.cron服务.web服务.FTP服务.sshd服务等. 服务是由已经在运行的进程 ...

  7. 为什么需要将网站封装为app?

      网站封装为app是一种宝贵的资源,为客户提供稳定的平台,一个网站也是一个有效的工具,用于企业与其客户之间的通信.企业网站用户可以通过他们的笔记本电脑,台式机,平板电脑,智能手机以及带有浏览器设备的 ...

  8. ECS7天实践进阶训练营Day5:使用ECS自建云端下载服务器

    一.概述 CCAA是服务器离线下载解决方案包,其组件中包含了Aria2提供了离线下载功能,能支持HTTP/HTTPS/FTP/BT/磁力链下载等常用离线下载模式及断点续传等功能.ccaa_web支撑于 ...

  9. DB2 分组查询语句ROW_NUMBER() OVER() (转载)

    说起 DB2 在线分析处理,可以用很好很强大来形容.这项功能特别适用于各种统计查询,这些查询用通常的SQL很难实现,或者根本就无发实现.首先,我们从一个简单的例子开始,来一步一步揭开它神秘的面纱,请看 ...

  10. Idea + maven搭建SSM框架

    1.打开idea,新建项目,选择maven骨架,然后填写包名和项目名称,一直下一步. 接着下一步,配置项目的maven环境 创建完成之后,如下图:(上边的项目名字只是例子,具体的以自己搭建的项目名为准 ...