Tag: ATI POS Import result add contains ITER on () next
Reprint Please specify source: http://www.cnblogs.com/skywang12345/p/3498995.html
Concurrentlinkedqueue Introduction
Concurrentlinkedqueue is a thread-safe queue that is suitable for "high concurrency" scenarios.
It is a link-based, line-free, thread-safe queue that sorts elements according to FIFO (first-out) principles. A null element cannot be placed in a queue element (except for a special node that is internally implemented).
concurrentlinkedqueue principles and data Structures
Concurrentlinkedqueue the data structure, as shown in:
Description :
1. Concurrentlinkedqueue inherits from Abstractqueue.
2. Concurrentlinkedqueue is implemented internally through a linked list. It contains both the head node and the tail node tail of the linked list. The Concurrentlinkedqueue sorts the elements according to the FIFO (first-in, in/out) principle. Elements are inserted from the tail into the linked list, returning from the head.
3. The type of next in the Concurrentlinkedqueue linked list node is volatile, and the type of the list data item is volatile. With regard to volatile, we know that its semantics include the following: "That is, the reading of a volatile variable, always see (any thread) the last write to this volatile variable". Concurrentlinkedqueue is the use of volatile to achieve multi-threaded access to competing resources mutually exclusive.
List of Concurrentlinkedqueue functions
Create a concurrentlinkedqueue that is initially empty. Concurrentlinkedqueue ()//Create a concurrentlinkedqueue that initially contains the given collection element, adding the elements in the order in which the collection iterators are traversed. Concurrentlinkedqueue (collection<? extends e> C)//inserts the specified element at the end of this queue. Boolean Add (E E)//returns True if this queue contains the specified element. Boolean contains (Object O)//Returns True if this queue does not contain any elements. Boolean isEmpty ()//Returns an iterator that iterates in the proper order on this queue element. Iterator<e> Iterator ()//inserts the specified element into the tail of this queue. Boolean offer (e E)//Gets the header of this queue without removing it, or null if this queue is empty. E peek ()//Gets and removes the header of this queue and returns null if this queue is empty. E poll ()//Removes a single instance of the specified element (if present) from the queue. Boolean remove (Object o)//Returns the number of elements in this queue. int size ()//Returns an array containing all elements of this queue in the proper order. Object[] ToArray ()//Returns an array containing all elements of this queue in the proper order; The run-time type of the returned array is the run-time type of the specified array.
<T> t[] ToArray (t[] a)
concurrentlinkedqueue Source Analysis (jdk1.7.0_40 version)
Concurrentlinkedqueue's complete source code is as follows:
View Code
The following is an analysis of the creation, addition, and deletion of these aspects from Concurrentlinkedqueue.
1 Create
The following is illustrated with Concurrentlinkedqueue ().
Public Concurrentlinkedqueue () { head = tail = new node<e> (null);}
description : In the constructor, create a new node with "content null," and set the value of the header head and footer tail to the new nodes.
Head and tail are defined as follows:
Private transient volatile node<e> head;private transient volatile node<e> tail;
Both head and tail are volatile types, and they have the meaning of volatile: "Reading a volatile variable will always see (any thread) the last write to this volatile variable".
Node declares the following:
private static class Node<e> {volatile E item; Volatile node<e> next; Node (E Item) {Unsafe.putobject (this, itemoffset, item); } Boolean Casitem (E cmp, E val) {return Unsafe.compareandswapobject (this, Itemoffset, CMP, Val); } void Lazysetnext (Node<e> val) {unsafe.putorderedobject (this, Nextoffset, Val); } Boolean Casnext (node<e> cmp, node<e> val) {return Unsafe.compareandswapobject (this, Nextoffset, C MP, Val); }//Unsafe mechanics private static final sun.misc.Unsafe unsafe; Private static final long itemoffset; Private static final long nextoffset; static {try {UNSAFE = Sun.misc.Unsafe.getUnsafe (); Class k = Node.class; Itemoffset = Unsafe.objectfieldoffset (K.getdeclaredfield ("item")); Nextoffset = Unsafe.objectfieldoffset (K.getdeclaredfield ("Next")); } catch (Exception e) {thRow new Error (e); } }}
Description :
Node is a one-way linked list nodes, and next is used to point to the next node,item for storing data. The APIs for node data manipulation are implemented through the CAS function of the unsafe mechanism; for example, Casnext () compares and sets the next node of a node through the CAS function.
2. Add
The following is an example of add (e E), which describes the additions in Concurrentlinkedqueue.
Public boolean Add (E-e) { return offer (e);}
Description : Add () is actually called an offer () to complete the add operation.
The source of offer () is as follows:
Public A Boolean offer (E e) { //check E is not null, if it throws a NullPointerException exception. Checknotnull (e); Create a new node final node<e> newNode = new node<e> (E); Add a new node to the end of the list. for (node<e> t = tail, p = t;;) { node<e> q = p.next; Case 1:q is null if (q = = null) { //CAS operation: If the next node of P is null (that is, p is the tail node), then the next node of P is set to NewNode. //If the CAS operation succeeds, compare "P and T" (if p is not equal to T, set NewNode to the new tail node) and return True. //If the CAS operation fails, which means "Other threads have modified the tail node", then the cycle is re-cycled. if (P.casnext (null, NewNode)) { if (P! = t)//hop of nodes at a time castail (T, NewNode); Failure is OK. return true; } } Conditions 2:p and Q equal else if (p = = q) p = (t! = (t = tail))? T:head; Scenario 3: Other else p = (P! = T && t! = (t = tail))? T:q;} }
Description : The role of Offer (E-e) is to add element e to the end of the list. The place to compare offer () is to understand the For loop, which distinguishes between 3 cases for the for analysis.
Case 1--Q is empty. This means that q is the next node of the tail node. At this point, the next node of "P" is set to NewNode by P.casnext (null, NewNode), and if the setting is successful, "P and T" (if p is not equal to T, then the NewNode is the new tail node) and returns True. Otherwise (meaning "Other threads have modified the tail node"), do nothing and proceed for the For loop.
P.casnext (NULL, NewNode) is called by CAs to operate on p. If "P's next node equals null", set "P's next node equals NewNode"; If the setting succeeds, it returns true, and False if it fails.
Case 2--p and q are equal. When will this happen? By "Case 3", we know that the value of P may be equal to Q after "Case 3" has been processed.
At this point, if the tail node does not change, then, should be the head node has changed, then set p as the head node, and then re-traverse the linked list; otherwise (the tail node changes), then set p as the tail node.
Situation 3--others.
We will p = (P! = T && t! = (t = tail))? t:q; Convert to the following code.
if (p==t) { p = q;} else { node<e> tmp=t; t = tail; if (tmp==t) { p=q; } else { p=t; }}
If p and T are equal, set p to Q. Otherwise, the "tail node is changed", if there is no change, then set p for Q; otherwise, set p to tail node.
The source code of Checknotnull () is as follows:
private static void Checknotnull (Object v) { if (v = = null) throw new NullPointerException ();
3. Delete
The following is an example of poll () to explain the deletion in Concurrentlinkedqueue.
Public E Poll () {//Set "tag" restartfromhead:for (;;) {for (node<e> h = head, p = h, q;;) {E item = P.item; Case 1//The data for the header is not NULL, and the "Set header data is null" operation succeeds; Compare "P and H" (if p!=h, the table header changes, the header is updated, that is, the table header is set to P), and the item value of the original header is returned. if (item = NULL && p.casitem (item, NULL)) {if (P! = h)//Hop nodes at a time Updatehead (H, ((q = p.next)! = null)? q:p); return item; }//Case 2//The next node of the header is null, that is, the list has only one "null-Content Header node". The table header is updated with P and returns null. else if ((q = p.next) = = null) {updatehead (H, p); return null; }//Case 3//This may be due to the occurrence of "condition 4" causing p=q, in which case the jump to the restartfromhead tag is re-operated. else if (p = = q) continue restartfromhead; Case 4//set p for q else p = q; } }}
Description : The function of poll () is to delete the table header node of the linked list and return the value corresponding to the truncated point. The implementation principle of poll () is similar to the offer (), where the following root divides or loops into 4 cases for analysis.
Case 1: "Data for the header node" is not null, and the "Set data for the header node is null" this operation succeeded.
P.casitem (item, NULL)--invokes the CAS function to compare the data value of node p with item equality, or NULL to set the data value of node p.
When Case 1 occurs, compare "P and H" and, if p!=h, the table header changes, call Updatehead () to update the table header, and then return the item value of the deleted node.
The source code of Updatehead () is as follows:
final void Updatehead (node<e> h, node<e> p) { if (h! = P && cashead (H, p)) h.lazysetnext (h);}
Description : The ultimate goal of Updatehead () is to update the table header to P and set h to the next node as H itself.
Cashead (H,P) is set by the CAS function table header, if the table header equals H, the table header is set to P.
The source code of Lazysetnext () is as follows:
void Lazysetnext (node<e> val) { unsafe.putorderedobject (this, Nextoffset, Val);}
Putorderedobject () function, which we introduced in the previous chapter "TODO". The role of H.lazysetnext (h) is to set H's next node to H itself through the CAS function, which may delay execution.
Case 2: If the next node of the table header is null, that is, the list has only one "null-Content Header node".
Call Updatehead (H, p), update the table header p, and return null.
Situation 3:p=q
When "Situation 4" occurs, it causes p=q, and "Situation 3" occurs. When "Condition 3" occurs, it jumps to the restartfromhead tag to re-operate.
Case 4: Other circumstances.
Set the p=q.
Concurrentlinkedqueue Example
1 Import java.util.*; 2 Import java.util.concurrent.*; 3 4/* 5 * concurrentlinkedqueue is a "thread-safe" queue, and LinkedList is non-thread-safe. 6 * 7 * Below is an example of "multiple threads working simultaneously and traversing the queue" 8 * (01) The program works correctly when the queue is a Concurrentlinkedqueue object. 9 * (02) When the queue is a LinkedList object, the program produces an concurrentmodificationexception exception. *11 * @author skywang12 */13 public class ConcurrentLinkedQueueDemo1 {//Todo:queue is a LinkedList object, the program will error. //private static queue<string> Queue = new linkedlist<string> (), + private static QUEUE<STRING&G T Queue = new concurrentlinkedqueue<string> (); public static void Main (string[] args) {19 20/start at the same time Two threads to work with the queue! New MyThread ("Ta"). Start (); New MyThread ("TB"). Start ();}24 private static void Printall () {-String value;27 Iterator iter = Queue.iterator (); while (Iter.hasnext ()) {V Alue = (String) iter.next (), System.out.print (value+ ","); 31}32 System.out.println (),}34, private static class MyThread extends Thread {MyThread (String nam e) {PNS super (name);}39 @Override40 public void Run () {0 int i =; while (i++ < 6) {43//"Thread name" + "-" + "ordinal"-String val = Thread.currentt Hread (). GetName () +i;45 Queue.add (Val), 46//through "Iterator" to traverse the queue. Printall (); 48}49}50}51}
Run results (one time) :
The result shows that if the queue in source code is changed to LinkedList object, the program will produce Concurrentmodificationexception exception.
Java and Contract--concurrentlinkedqueue