In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains "what are the five queues in Java". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "what are the five queues in Java"?
Blocking queue and non-blocking queue
Blocking queues (Blocking Queue) provide blocking put and take methods, which are equivalent to timed offer and poll. If the queue is full, the put method will be blocked until space is available before inserting the element; if the queue is empty, the take method will also block until an element is available. When the queue is never full, the put and take methods never block.
We can know from the name of the queue whether the queue is a blocking queue, which contains the BlockingQueue keyword, such as the following:
ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueue. Demonstration of blocking queue function
Next, let's demonstrate what happens when the blocking queue is full. The sample code is as follows:
Import java.util.Date
Import java.util.concurrent.ArrayBlockingQueue
Public class BlockingTest {
Public static void main (String [] args) throws InterruptedException {
/ / create a blocking queue of length 5
ArrayBlockingQueue Q1 = new ArrayBlockingQueue (5)
/ / create a new thread to execute listing
New Thread (()-> {
/ / cycle 10 times
For (int I = 0; I
< 10; i++) { try { q1.put(i); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(new Date() + " | ArrayBlockingQueue Size:" + q1.size()); } System.out.println(new Date() + " | For End."); }).start(); // 新创建一个线程执行出列 new Thread(() ->{
For (int I = 0; I
< 5; i++) { try { // 休眠 1S Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } if (!q1.isEmpty()) { try { q1.take(); // 出列 } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } } 以上代码的执行结果如下: Mon Oct 19 20:16:12 CST 2020 | ArrayBlockingQueue Size:1 Mon Oct 19 20:16:12 CST 2020 | ArrayBlockingQueue Size:2 Mon Oct 19 20:16:12 CST 2020 | ArrayBlockingQueue Size:3 Mon Oct 19 20:16:12 CST 2020 | ArrayBlockingQueue Size:4 Mon Oct 19 20:16:12 CST 2020 | ArrayBlockingQueue Size:5 Mon Oct 19 20:16:13 CST 2020 | ArrayBlockingQueue Size:5 Mon Oct 19 20:16:14 CST 2020 | ArrayBlockingQueue Size:5 Mon Oct 19 20:16:15 CST 2020 | ArrayBlockingQueue Size:5 Mon Oct 19 20:16:16 CST 2020 | ArrayBlockingQueue Size:5 Mon Oct 19 20:16:17 CST 2020 | ArrayBlockingQueue Size:5 Mon Oct 19 20:16:17 CST 2020 | For End. 从上述结果可以看出,当 ArrayBlockingQueue 队列满了之后就会进入阻塞,当过了 1 秒有元素从队列中移除之后,才会将新的元素入列。 非阻塞队列 非阻塞队列也就是普通队列,它的名字中不会包含 BlockingQueue 关键字,并且它不会包含 put 和 take 方法,当队列满之后如果还有新元素入列会直接返回错误,并不会阻塞的等待着添加元素,如下图所示:Typical representatives of non-blocking queues are ConcurrentLinkedQueue and PriorityQueue.
Bounded queue and unbounded queue
Bounded queue: a queue with a fixed size, such as a fixed size ArrayBlockingQueue, or a SynchronousQueue with a size of 0.
Unbounded queue: refers to a queue that does not have a fixed size, but in fact, there is a default value if the fixed size is not set, but the default value is Integer.MAX_VALUE, of course, there will not be such a large capacity in actual use (more than Integer.MAX_VALUE), so it is equivalent to "unbounded" from the user's point of view.
Classify by function
Next is the focus of this article, we divide the queue by function, it can be divided into: ordinary queue, priority queue, double-ended queue, delay queue, other queues and so on.
1. Ordinary queue
Queue refers to basic queues that implement FIFO, such as ArrayBlockingQueue and LinkedBlockingQueue, where ArrayBlockingQueue is a normal queue implemented in an array, as shown in the following figure:
LinkedBlockingQueue is a normal queue implemented using a linked list, as shown in the following figure:
Common methods
The common methods in normal queues are as follows:
Offer (): add elements. If the queue is full, return false directly. If the queue is not full, insert and return true;poll (): delete and return the queue header element, and return null;add when the queue column is empty (): add elements, this method is a simple encapsulation of the offer method, and throw an IllegalStateException exception if the queue is full; remove (): delete the queue header element directly Put (): add elements, if the queue is full, it will block waiting for insertion; take (): delete and return the queue header element, when the queue is empty, it will block the wait; peek (): query the queue header element, but will not delete it; element (): simply encapsulate the peek method, take it out and not delete it if the queue header element exists, and throw a NoSuchElementException exception if there is no exception.
Note: in general, the offer () and poll () methods are used together, the put () and take () blocking methods are used together, the add () and remove () methods are used together, and the offer () and poll () methods are commonly used in the program, so these two methods are friendly and will not report errors.
Let's take LinkedBlockingQueue as an example to demonstrate the use of a normal queue:
Import java.util.concurrent.LinkedBlockingQueue
Static class LinkedBlockingQueueTest {
Public static void main (String [] args) {
LinkedBlockingQueue queue = new LinkedBlockingQueue ()
Queue.offer ("Hello")
Queue.offer ("Java")
Queue.offer ("Chinese Community")
While (! queue.isEmpty ()) {
System.out.println (queue.poll ())
}
}
}
The execution result of the above code is as follows:
Hello
Java
Chinese community
two。 Double-ended queue
Double-end queue (Deque) refers to the data structure in which both the head and tail of the queue can be joined and dequeued at the same time, as shown in the following figure:
Next, let's demonstrate the use of double-ended queue LinkedBlockingDeque:
Import java.util.concurrent.LinkedBlockingDeque
/ * *
* double-ended queue example
, /
Static class LinkedBlockingDequeTest {
Public static void main (String [] args) {
/ / create a double-ended queue
LinkedBlockingDeque deque = new LinkedBlockingDeque ()
Deque.offer ("offer"); / / insert the first element
Deque.offerFirst ("offerFirst"); / / insert elements at the head of the line
Deque.offerLast ("offerLast"); / / insert elements at the end of the line
While (! deque.isEmpty ()) {
/ / iterate through printing from scratch
System.out.println (deque.poll ())
}
}
}
The execution result of the above code is as follows:
OfferFirst
Offer
OfferLast
3. Priority queue
Priority queue (PriorityQueue) is a special kind of queue, which is not first-in, first-out, but first-out elements with high priority.
The priority queue is based on the binary heap, and the data structure of the binary heap is shown in the following figure:
There are two types of binary heaps: the largest heap and the smallest heap. Shown above is the largest heap, in which the value of any parent node is greater than or equal to the value of its left and right child nodes.
Because the priority queue is based on the binary heap, it can dequeue the elements with the best priority first.
Next, let's demonstrate the use of priority queues:
Import java.util.PriorityQueue
Public class PriorityQueueTest {
/ / Custom entity class
Static class Viper {
Private int id; / / id
Private String name; / / name
Private int level; / / rating
Public Viper (int id, String name, int level) {
This.id = id
This.name = name
This.level = level
}
Public int getId () {
Return id
}
Public void setId (int id) {
This.id = id
}
Public String getName () {
Return name
}
Public void setName (String name) {
This.name = name
}
Public int getLevel () {
Return level
}
Public void setLevel (int level) {
This.level = level
}
}
Public static void main (String [] args) {
PriorityQueue queue = new PriorityQueue (10, new Comparator () {
@ Override
Public int compare (Viper v1, Viper v2) {
/ / set priority rules (in reverse order, the higher the level, the greater the permissions)
Return v2.getLevel ()-v1.getLevel ()
}
});
/ / build entity classes
Viper v1 = new Viper (1, "Java", 1)
Viper v2 = new Viper (2, "MySQL", 5)
Viper v3 = new Viper (3, "Redis", 3)
/ / list
Queue.offer (v1)
Queue.offer (v2)
Queue.offer (v3)
While (! queue.isEmpty ()) {
/ / traversal name
Viper item = (Viper) queue.poll ()
System.out.println ("Name:" + item.getName () +
"Level:" + item.getLevel ()
}
}
}
The execution result of the above code is as follows:
Name:MySQL Level:5
Name:Redis Level:3
Name:Java Level:1
As can be seen from the above results, the priority queue does not consider the order of joining the queue, and it always follows the elements with high priority to leave the queue first.
4. Delay queue
Delay queue (DelayQueue) is implemented based on priority queue PriorityQueue, which can be regarded as a priority queue measured in time, and can not be dequeued until the elements in the queue reach the specified delay time.
Let's demonstrate the use of delay queues:
Import lombok.Getter
Import lombok.Setter
Import java.text.DateFormat
Import java.util.Date
Import java.util.concurrent.DelayQueue
Import java.util.concurrent.Delayed
Import java.util.concurrent.TimeUnit
Public class CustomDelayQueue {
/ / delayed message queuing
Private static DelayQueue delayQueue = new DelayQueue ()
Public static void main (String [] args) throws InterruptedException {
Producer (); / / call the producer
Consumer (); / / invoke the consumer
}
/ / producer
Public static void producer () {
/ / add message
DelayQueue.put (new MyDelay (1000, "message 1"))
DelayQueue.put (new MyDelay (3000, "message 2"))
}
/ / consumers
Public static void consumer () throws InterruptedException {
System.out.println ("start execution time:" +
DateFormat.getDateTimeInstance () .format (new Date ())
While (! delayQueue.isEmpty ()) {
System.out.println (delayQueue.take ())
}
System.out.println ("end execution time:" +
DateFormat.getDateTimeInstance () .format (new Date ())
}
Static class MyDelay implements Delayed {
/ / delay deadline (in milliseconds)
Long delayTime = System.currentTimeMillis ()
/ / implemented with lombok
@ Getter
@ Setter
Private String msg
/ * *
* initialization
* @ param delayTime sets the delayed execution time
* @ param msg executed message
, /
Public MyDelay (long delayTime, String msg) {
This.delayTime = (this.delayTime + delayTime)
This.msg = msg
}
/ / get the remaining time
@ Override
Public long getDelay (TimeUnit unit) {
Return unit.convert (delayTime-System.currentTimeMillis (), TimeUnit.MILLISECONDS)
}
/ / elements in the queue are sorted by
@ Override
Public int compareTo (Delayed o) {
If (this.getDelay (TimeUnit.MILLISECONDS) > o.getDelay (TimeUnit.MILLISECONDS)) {
Return 1
} else if (this.getDelay (TimeUnit.MILLISECONDS))
< o.getDelay(TimeUnit.MILLISECONDS)) { return -1; } else { return 0; } } @Override public String toString() { return this.msg; } } } 以上代码的执行结果如下: 开始执行时间:2020-10-20 20:17:28 消息1 消息2 结束执行时间:2020-10-20 20:17:31 从上述结束执行时间和开始执行时间可以看出,消息 1 和消息 2 都正常实现了延迟执行的功能。 5.其他队列 在 Java 的队列中有一个比较特殊的队列 SynchronousQueue,它的特别之处在于它内部没有容器,每次进行 put() 数据后(添加数据),必须等待另一个线程拿走数据后才可以再次添加数据,它的使用示例如下: import java.util.concurrent.SynchronousQueue; public class SynchronousQueueTest { public static void main(String[] args) { SynchronousQueue queue = new SynchronousQueue(); // 入队 new Thread(() ->{
For (int I = 0; I
< 3; i++) { try { System.out.println(new Date() + ",元素入队"); queue.put("Data " + i); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); // 出队 new Thread(() ->{
While (true) {
Try {
Thread.sleep (1000)
System.out.println (new Date () + ", element out of line:" + queue.take ())
} catch (InterruptedException e) {
E.printStackTrace ()
}
}
}) .start ()
}
}
The execution result of the above code is as follows:
Mon Oct 19 21:00:21 CST 2020, elements join the team
Mon Oct 19 21:00:22 CST 2020, element out: Data 0
Mon Oct 19 21:00:22 CST 2020, elements join the team
Mon Oct 19 21:00:23 CST 2020, element out: Data 1
Mon Oct 19 21:00:23 CST 2020, elements join the team
Mon Oct 19 21:00:24 CST 2020, element out: Data 2
As can be seen from the above results, when an element is queued, the new element cannot join the queue again until another thread has dequeued it.
Thank you for your reading, the above is the content of "what are the five queues in Java". After the study of this article, I believe you have a deeper understanding of what the five queues in Java are, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.