在前面我们提到了阻塞队列,也用过了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三引号

    Python三引号:多用作注释.数据库语句.编写 HTML 文本. strs = ''' 使用了三引号的字符串 ''' print (strs) # 在 ‘’‘ 里可以使用转义字符 strs = '' ...

  2. Django学习路23_if else 语句,if elif else 语句 forloop.first第一个元素 .last最后一个元素,注释

    if else 格式 {% if 条件 %} <标签>语句</标签> {%else%} <标签>语句</标签> {%endif} 标签都可以添加样式 { ...

  3. PHP end() 函数

    实例 输出数组中的当前元素和最后一个元素的值: <?php$people = array("Peter", "Joe", "Glenn" ...

  4. 这届 Showgirl行不行?AI告诉你谁是ChinaJoy上最漂亮的小姐姐

    摘要: CJ开幕,顶着三伏天的酷暑高温,暴走一整天,就为了拍点漂亮小姐姐给大家看看. 一年一度的游戏视觉盛宴又来了! 作为一个游戏动漫控的肥宅,去CJ现场是必须的.除了看看游戏和动漫,各大游戏展台漂亮 ...

  5. OpenVINO学习系列1

    OpenVINO介绍 OpenVINO是英特尔推出一套基于深度学习的计算机视觉加速优化框架,支持其它机器学习平台模型的压缩优化.加速计算等功能. 自发布以后就得到开发者的青睐,其强大的模型优化与压缩能 ...

  6. Idea风格的快捷键

    在使用IntelliJ IDEA时,是可以定义快捷键风格的:File --> Setting --> Keymap 里进行选择,因为我以前用Eclipse开发,后来换成Idea有2年的时间 ...

  7. 2080ti的各种问题

    1.循环登录 https://blog.csdn.net/miclover_feng/article/details/79201865 2.多版本cuda切换 https://blog.csdn.ne ...

  8. __getattribute__和item系列

    # class Foo: # def __init__(self,x): # self.x=x # # def __getattr__(self, item): # print('执行的是我') # ...

  9. Python内置OS模块用法详解

    大家好,从今天起早起Python将持续更新由小甜同学从初学者的角度学习Python的笔记,其特点就是全文大多由新手易理解的代码与注释及动态演示.刚入门的读者千万不要错过! 很多人学习python,不知 ...

  10. 基于Socket访问西门子PLC系列教程(二)

    本文是西门子开放式TCP通信的第2篇,上一篇我们讲了使用西门子1200PLC作为TCP服务器的程序编写,可以点击下方链接阅读:[公众号dotNet工控上位机:thinger_swj] 基于Socket ...