Java Concurrency Programming (8) Atomic variables and non-blocking synchronization mechanisms

Source: Internet
Author: User
Tags cas volatile

Atomic variable and non-blocking synchronization mechanism one, the disadvantage of the lock

1. Under Multi-thread: The lock hangs and restores the process to have the very big overhead (in time modern JVM will decide when to use hangs, when spins the wait)

2.volatile: Lightweight synchronization mechanism, but cannot be used to build atomic composite operations

Therefore: there needs to be a way to manage the competition between threads in a finer grained way, similar to the volatile mechanism, while also supporting atomic update operations

Second, CAS

An exclusive lock is a pessimistic technique-it assumes the worst case, so each thread is exclusive

CAS Compare and Exchange: Compareandswap/set (A, B): We think the memory value is a, if it is a, modify it to B, otherwise do not operate; Returns the original value at memory or whether the modification succeeded

Example: simulating CAS operations

//Simulation of CAs Public classSimulatedcas {Private intvalue;  Public synchronized intget () {returnvalue; }    //CAS Operations     Public synchronized intCompareandswap (intExpectedvalue,intnewvalue) {        intOldValue =value; if(OldValue = =expectedvalue) {Value=NewValue; }        returnOldValue; }     Public synchronized BooleanCompareandset (intExpectedvalue,intnewvalue) {        return(Expectedvalue = =Compareandswap (Expectedvalue, newvalue)); }}//Typical usage Scenarios Public classCascounter {PrivateSimulatedcas value;  Public intGetValue () {returnValue.get (); }     Public intincrement () {intv;  Do{v=Value.get (); }  while{(v! = Value.compareandswap (V, v + 1)); }        returnV + 1; }}

Java provides the operation of CAs

Atomic State Class: CAs method for atomicxxx

JAVA7/8: Operation of Map: Putifabsent, computerifabsent, computerifpresent ...

Third, the Atomic variable class

The Atomicrefence atom updates an object, which can be a custom object, such as:

 Public classCasnumberrange {Private Static classIntpair {//invariant:lower <= Upper        Final intLower//To define a value as an immutable domain        Final intUpper//To define a value as an immutable domain         PublicIntpair (intLowerintUpper) {             This. Lower =Lower;  This. Upper =Upper; }    }    Private Finalatomicreference<intpair> values =NewAtomicreference<intpair> (NewIntpair (0, 0));//Encapsulating Objects     Public intGetlower () {returnvalues.get (). Lower; }     Public intGetupper () {returnvalues.get (). Upper; }     Public voidSetlower (inti) { while(true) {Intpair OLDV=Values.get (); if(I >oldv.upper) {Throw NewIllegalArgumentException ("Can ' t set lower to" + i + "> upper"); } Intpair NEWV=NewIntpair (i, oldv.upper);//property is an immutable domain, the new object is updated every time            if(Values.compareandset (OLDV, NEWV)) {//Atomic Update, if the thread is modified during the process, the other threads will not be updated successfully because the OLDV and memory values are different                return; }        }    }    //Ibid .     Public voidSetupper (inti) { while(true) {Intpair OLDV=Values.get (); if(I <oldv.lower)Throw NewIllegalArgumentException ("Can ' t set Upper to" + i + "< lower"); Intpair NEWV=NewIntpair (Oldv.lower, i); if(Values.compareandset (OLDV, NEWV))return; }    }}

Performance issues: Using atomic variables in medium-low concurrency (competition) is faster than using lock speed, typically faster than lock speed

Four, non-blocking algorithm

Non-blocking algorithms can be used in many common data structures

Non-blocking algorithm: in multi-threading, the success of the work is uncertain, need to loop execution, and atomic operation through CAs

1, the above Casnumberrange

2, stack of non-blocking algorithm: Only save the head pointer, only one state

//non-blocking algorithm for stack implementation: one-way linked list Public classConcurrentstack <E>{atomicreference<Node<E>> top =NewAtomicreference<node<e>>();  Public voidpush (E item) {Node<E> Newhead =NewNode<e>(item); Node<E>Oldhead;  Do{Oldhead=Top.get (); Newhead.next=Oldhead; }  while(!top.compareandset (Oldhead, Newhead));//CAS operations: Atomic update operation, cyclic judgment, non-blocking    }     PublicE Pop () {Node<E>Oldhead; Node<E>Newhead;  Do{Oldhead=Top.get (); if(Oldhead = =NULL) {                return NULL; } newhead=Oldhead.next; }  while(!top.compareandset (Oldhead, Newhead));//CAS operations: Atomic update operation, cyclic judgment, non-blocking        returnOldhead.item; }    Private Static classNode <E> {         Public FinalE Item;  PublicNode<e>Next;  PublicNode (E item) { This. Item =item; }    }}

3, the non-blocking algorithm of the list: Head and tail of fast access, save two states, more complex

 Public classLinkedqueue <E> {    Private Static classNode <E> {        FinalE Item; FinalAtomicreference<linkedqueue.node<e>>Next;  PublicNode (E item, linkedqueue.node<e>next) {             This. Item =item;  This. Next =NewAtomicreference<linkedqueue.node<e>>(next); }    }    Private Finallinkedqueue.node<e> dummy =NewLinkedqueue.node<e> (NULL,NULL); Private FinalAtomicreference<linkedqueue.node<e>> head =NewAtomicreference<linkedqueue.node<e>>(dummy); Private Finalatomicreference<linkedqueue.node<e>> tail =NewAtomicreference<linkedqueue.node<e>> (dummy);//Save Tail Node     Public Booleanput (E item) {Linkedqueue.node<E> NewNode =NewLinkedqueue.node<e> (Item,NULL);  while(true) {Linkedqueue.node<E> curtail =Tail.get (); Linkedqueue.node<E> Tailnext =CurTail.next.get (); if(Curtail = =Tail.get ()) {                if(Tailnext! =NULL) {                    //in the middle state, update the tail node to the next of the current tail nodeTail.compareandset (curtail, tailnext); } Else {                    //set next to the current tail node as a new node: Linked list                    if(CurTail.next.compareAndSet (NULL, NewNode)) {                        /*** This is the middle state, although there are two atomic operations here, the whole is not atomic, but through the algorithm to ensure security: * cause is in the middle state, if there are other threads come in Operation, the above if will execute; * The above if operation is to help the current thread to complete the update tail node operation, and the current thread's update will fail to return, eventually the update succeeds*/                                                //The link succeeds, the tail node has changed, then the current tail node is set to the new nodeTail.compareandset (curtail, newNode); return true; }                }            }        }    }}

3. Atomic Domain Updater

The above logic realizes the non-blocking algorithm of the linked list, using node to save the head node and tail nodes

In the actual concurrentlinkedqueue, a reflection-based atomicreferencefiledupdater is used to wrap the node

V. the problem of ABA

Issues that are prone to CAS operations:

Determine whether the value is a, yes, continue to update the operation to change to B;

However, if a thread changes the value A to C and then changes back to a, the original thread will determine that a=a successfully performed the update operation;

If you change a to C and then back to a operation, you also need to consider the changes, you need to optimize the algorithm

FIX: Add version number, each update operation to update version number, even if the value is the same

      

Java Concurrency Programming (8) Atomic variables and non-blocking synchronization mechanisms

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.