共计 4434 个字符,预计需要花费 12 分钟才能阅读完成。
作者:废物大师兄 \
起源:www.cnblogs.com/cjsblog/p/14140441.html
当用户超时未领取时,给用户发揭示音讯。
另一种场景是,超时未付款,订单主动勾销。
通常,订单创立的时候能够向提早队列种插入一条音讯,到工夫主动执行。
其实,也能够用长期表,把这些未领取的订单放到一个长期表中,或者 Redis,而后定时工作去扫描。
这里咱们用延时队列来做,RocketMQ 有延时队列,RibbitMQ 也能够实现,Java 自带的也有延时队列,接下来就回顾一下各种队列。
Queue
队列是一种汇合。
除了根本的汇合操作以外,队列还提供了额定的插入、提取和查看操作。
队列的每个办法都以两种模式存在:一种是当操作失败时抛异样,另一种是返回一个特定的值(null 或者 false,取决于具体操作)。
后一种模式的插入操作是专门设计用于有界队列实现的,在大多状况下,插入操作不会失败。
队列通常(但不肯定)以 FIFO(先进先出)的形式对元素进行排序。例外情况包含优先级队列(依据提供的比拟器对元素进行排序或元素的天然排序)和 LIFO 队列(或堆栈),对 LIFO 进行排序(后进先出)。
无论应用哪种程序,队列的结尾都是该元素,能够通过调用 remove()或 poll()将其删除。在 FIFO 队列中,所有新元素都插入队列的尾部。其余品种的队列可能应用不同的搁置规定。每个 Queue 实现必须指定其排序属性。无论应用哪种程序,都能够通过调用 remove() 或 poll() 来删除队列结尾的元素。
在 FIFO 队列中,所有新元素都插入到队列的尾部。其余类型的队列可能应用不同的搁置规定。每个队列实现都必须指定其排序属性。
offer 办法在能够的状况下会向队列种插入一个元素,否则返回 false。这不同于 Collection.add 办法,后者只能通过抛异样来增加元素。offer 办法设计用于在失常状况下(而不是在例外情况下)产生故障时,例如在固定容量(或者“有界”)队列种应用。
remove() 和 poll() 办法删除并返回队头元素。当队列为空时,remove() 抛出异样,而 poll() 返回 null。
element() 和 peek() 办法返回队头元素。
PriorityQueue
PriorityQueue 是一个无界优先级队列是基于优先级堆的。优先级队列种的元素依据天然程序进行排序,或者通过在队列构建时提供的 Comparator 进行排序,当然这取决于应用哪种构造函数。优先级队列不容许空(null)元素。一个依赖天然程序的优先级队列也不容许插入不可比拟的对象。
优先级队列的队头元素是最小的元素,如果有多个元素并列最小,那么队头是它们其中之一。
优先级队列是无界的,然而有一个外部容量来管制用于在队列上存储元素的数组的大小。它总是至多与队列大小一样大。将元素增加到优先级队列时,其容量会主动增长。
BlockingQueue
这种队列还反对以下操作:在检索元素时期待队列变为非空,并在存储元素时期待队列中的空间变为可用。
BlockingQueue 办法有四种模式,它们以不同的形式解决操作,这些操作无奈立刻满足,但未来可能会满足:一种抛出异样,第二种返回非凡值(null 或 false,取决于具体操作),第三种阻塞以后线程,直到操作胜利为止;第四种阻塞以后线程,超时则放弃。下表总结了这些办法:
阻塞队列不承受空元素,如果你试图 add , put 或者 offer 一个 null,将会抛 NullPointerException。
阻塞队列是线程平安的。所有排队办法都应用外部锁或者其余模式的并发管制来保障以原子形式实现它们的成果。
阻塞队列被设计次要用于生产者 - 消费者队列。
上面是一个典型的生产者 - 消费者计划:
package com.example;
import java.text.MessageFormat;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @author ChengJianSheng
* @date 2020/12/15
*/
public class Setup {public static void main(String[] args) {BlockingQueue<Bread> queue = new ArrayBlockingQueue<>(5);
Producer p1 = new Producer(queue);
Producer p2 = new Producer(queue);
Consumer c1 = new Consumer(queue);
Consumer c2 = new Consumer(queue);
new Thread(p1, "p1").start();
new Thread(p2, "p2").start();
new Thread(c1, "c1").start();
new Thread(c2, "c2").start();}
}
class Bread {
}
/**
* 生产者
*/
class Producer implements Runnable {
private final BlockingQueue<Bread> queue;
public Producer(BlockingQueue<Bread> queue) {this.queue = queue;}
@Override
public void run() {
try {while (true) {queue.put(produce());
}
} catch (InterruptedException e) {e.printStackTrace();
}
}
public Bread produce() {
try {Thread.sleep(Math.round(2000));
} catch (InterruptedException e) {e.printStackTrace();
}
return new Bread();}
}
/**
* 消费者
*/
class Consumer implements Runnable {
private final BlockingQueue<Bread> queue;
public Consumer(BlockingQueue<Bread> queue) {this.queue = queue;}
@Override
public void run() {
try {while (true) {consume(queue.take());
}
} catch (InterruptedException e) {e.printStackTrace();
}
}
public void consume(Bread bread) {
try {Thread.sleep(Math.round(2000));
} catch (InterruptedException e) {e.printStackTrace();
}
}
}
ArrayBlockingQueue
ArrayBlockingQueue 是用数组实现的有界阻塞队列。这种队列中的元素按 FIFO(先进先出)排序。队头是在队列中停留最长工夫的元素。队尾是在队列中停留时间最短的元素。新元素插入到队列的尾部,并且队列检索操作在队列的头部获取元素。
这是一个经典的“有界缓冲区”,其中固定大小的数组蕴含由生产者插入并由消费者提取的元素。创立后,容量将无奈更改。试图将一个元素放入一个已满的队列将导致操作阻塞;试图从空队列中取出一个元素也会阻塞。
这个类反对一个可选的公平性策略,用于对期待的生产者和消费者线程进行排序。默认状况下,不保障这个程序。然而,将公平性设置为 true 的队列将按 FIFO 程序授予线程拜访权。公平性通常会升高吞吐量,但会升高可变性并防止饥饿。
LinkedBlockingQueue
LinkedBlockingQueue 是一个基于链表实现的可选边界的阻塞队列。
PriorityBlockingQueue
PriorityBlockingQueue 是一个无界阻塞队列,它应用与 PriorityQueue 雷同的排序规定,并提供阻塞检索操作。
DelayQueue
DelayQueue 是一种由提早元素组成的无界阻塞队列,在该队列中,仅当元素的提早到期时才能够应用该元素。队头是曾经过期的提早元素,它已过期工夫最长。如果没有过期的提早,则队列没有头部,此时调用 poll 将返回 null。当调用元素的 getDelay(TimeUnit.NANOSECONDS) 办法返回值小于或等于 0 时,就会产生过期。即便元素没有过期,也不能用 take 或者 poll 将其删除。
AbstractQueuedSynchronizer
AbstractQueuedSynchronizer 提供了一个框架来实现依赖于先进先出(FIFO)期待队列的阻塞锁和相干的同步器(信号灯,事件等)。该类旨在为大多数依赖单个原子 int 值示意状态的同步器提供有用的根底。子类必须定义更改此状态的受爱护办法,并定义该状态对于获取或开释此对象而言意味着什么。鉴于这些,此类中的其余办法将执行所有排队和阻塞机制。子类能够保护其余状态字段,然而仅跟踪对于同步的应用办法 getState(),setState(int)和 compareAndSetState(int,int)操作的原子更新的 int 值。
小结
1、Queue 是一个汇合,队列的每个办法都有两种模式,一种是抛异样,另一种是返回一个特定的值。
2、PriorityQueue 是一个无界优先级队列,默认状况下,队列种的元素按天然程序排序,或者依据提供的 Comparator 进行排序。也就是说,优先级队列种的元素都是通过排序的,排序规定能够本人指定,同时队列种的元素都必须是可排序的。
3、BlockingQueue 是一个阻塞队列,向已满的队列种插入元素时会阻塞,向空队列中取元素时也会阻塞;阻塞队列被设计次要用于生产者 - 消费者队列。
4、ArrayBlockingQueue 是用数组实现的有界阻塞队列,队列种的元素按 FIFO(先进先出)排序。
5、LinkedBlockingQueue 是用链表实现的可选边界的阻塞队列。
6、PriorityBlockingQueue 相当于是阻塞队列和优先级队列的合体,排序规定与优先级队列雷同。
7、DelayQueue 延时队列中的元素都有一个有效期,只有当过了有效期才能够应用该元素。
关注公众号 Java 技术栈,在后盾回复:面试,能够获取我整顿的 MySQL 系列面试题和答案。
近期热文举荐:
1.600+ 道 Java 面试题及答案整顿 (2021 最新版)
2. 终于靠开源我的项目弄到 IntelliJ IDEA 激活码了,真香!
3. 阿里 Mock 工具正式开源,干掉市面上所有 Mock 工具!
4.Spring Cloud 2020.0.0 正式公布,全新颠覆性版本!
5.《Java 开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞 + 转发哦!