In concurrent programming, it is sometimes necessary to use thread-safe queues. There are two ways to implement a thread-safe queue: One is to use a blocking algorithm and the other is to use a non-blocking algorithm.
Queues using blocking algorithms can be implemented with a lock (team and outbound with the same lock) or two locks (team and outbound with different locks).
Non-blocking implementations can be implemented using a cyclic CAS approach. Concurrentlinkedqueue
Let's look at how to implement thread-safe queue concurrentlinkedqueue using a non blocking method.
Concurrentlinkedqueue is a line-free secure queue based on link nodes, which uses FIFO rules to sort nodes, and when we add an element, it is added to the tail of the queue; when we get an element, it returns the elements of the queue's head. concurrentlinkedqueue Structure
public class Concurrentlinkedqueue<e> extends abstractqueue<e>
implements Queue<e>, java.io.Serializable {
Private transient volatile node<e> head;//head pointer
private transient volatile e> tail;//tail pointer public
concurrentlinkedqueue () {//initialized, head=tail= (an empty header node) head
= tail = new Node<e> ( NULL);
private static class Node<e> {
volatile E item;
Volatile node<e> next;//internally is implemented using one-way linked lists ...
}
......
}
Team
public Boolean offer (E e) {checknotnull (e); Final node<e> NewNode = new node<e> (E);//Before the team, create a node for (node<e> t = tail, p = t;;)
{///unless the insert succeeds and returns, repeat cycle node<e> q = p.next; if (q = = null) {//P is the last node if (P.casnext (null, NewNode)) {//////with CAS operation, P's next pointer from old value NU ll update to NewNode if (P!= t)//Hop two nodes at a time castail (T, NewNode);
Failure is OK. Update tail with CAS operations, if the failure indicates that other threads have added elements, the other thread is responsible for updating tail return true; }//Lost CAS Race to another thread; Re-read next if adding an element fails, the other thread adds the element, p moves back, and continues to try} else if (p = = q)//If P is removed from the list, we need to adjust the pointer to point to head again, otherwise we point to New tail p = (t!= (t = tail))?
T:head; else//p point to tail or q p = (P!= t && t!= (t = tail))?
T:q; }
}
The Castail (Cmp,value) method is used to update the tail node. Tail is set to volatile to ensure visibility.
The P.casnext (Cmp,value) method is used to set the queue node as the next node in the tail node of the current queues. Value is also set to volatile.
For outbound operations, it is also a way of looping through the use of CAs to remove elements from the head.
Because of the CAS operation, multiple threads are allowed to execute concurrently, and the threads are not blocked because of locking, which makes the concurrency performance better. blocking queues in Java
This section describes what a blocking queue is and 4 ways to block queues in Java, describes the 7 blocking queues provided in Java 7, and finally analyzes one implementation of the blocking queues.
What is a blocking queue blocking queue (blockingqueue) is a queue that supports two additional operations. These two additional operations support blocking insertion and removal methods.
1 Support blocking insertion method: Meaning when the queue is full, the queue blocks the thread that inserts the element until the queue is dissatisfied.
2 Support blocking removal method: meaning that when the queue is empty, the thread that gets the element waits for the queue to become non-empty.
Blocking queues are often used for producer and consumer scenarios where the producer is the thread that adds elements to the queue, and the consumer is the thread that takes the element from the queue. A blocking queue is a container that producers use to store elements and consumers to get elements.
JDK 7 provides 7 blocking queues, as follows.
· Arrayblockingqueue: A bounded blocking queue consisting of an array structure.
· Linkedblockingqueue: A bounded blocking queue consisting of a list structure.
· Priorityblockingqueue: An unbounded blocking queue that supports priority sorting.
· Delayqueue: An unbounded blocking queue implemented using a priority queue.
· Synchronousqueue: A blocking queue that does not store elements.
· LinkedTransferQueue: An unbounded blocking queue consisting of a list structure.
· Linkedblockingdeque: A two-way blocking queue consisting of a linked list structure.
Content from:
The Art of concurrent programming