Java concurrent programming principle and Combat 43: ABA Problem----CAS

Source: Internet
Author: User

ABA problems caused by CAS (Compare and Swap)

Problem description

In multi-threaded situations, each thread uses CAS operations to modify data A to B, but we only want one thread to modify the data correctly and modify it only once. When concurrency, one of the threads has changed a successfully to B, but the thread concurrent scheduling process has not yet been dispatched, during this period, another thread (not in the concurrent request thread) B is modified to a, then the original thread in the concurrency can be a CAS operation to change a to B

Test Case:

 Public classAbapro {Private Static FinalRandom random =NewRandom (); Private Static FinalString B = "B"; Private Static FinalString a = "a";  Public Static FinalAtomicreference<string> atomic_reference =NewAtomicreference<>(A);  Public Static voidMain (string[] args)throwsinterruptedexception {FinalCountdownlatch Startlatch =NewCountdownlatch (1); thread[] Threads=NewThread[20];  for(inti=0; I < 20; i++) {Threads[i]=NewThread () {@Override Public voidrun () {String OldValue=Atomic_reference.get (); Try{startlatch.await (); } Catch(interruptedexception e) {e.printstacktrace (); }                    Try{thread.sleep (Random.nextint ()&500); } Catch(interruptedexception e) {e.printstacktrace (); }                    if(Atomic_reference.compareandset (OldValue, B)) {System.out.println (Thread.CurrentThread (). Getn Ame ()+ "The original value has been modified, this value is:" +atomic_reference.get ());            }                }            };        Threads[i].start ();        } startlatch.countdown (); Thread.Sleep (200); NewThread () {@Override Public voidrun () {Try{thread.sleep (Random.nextint ()& 200); } Catch(interruptedexception e) {e.printstacktrace (); } String oldval=Atomic_reference.get ();  while(!Atomic_reference.compareandset (Atomic_reference.get (), A)); System.out.println (Thread.CurrentThread (). GetName ()+ "The value" +oldval+ "has been modified to the original value: A");    }}.start (); }}

Results:

Thread-12 已经对原始值进行了修改,此时值为: BThread-20 已经将值 B 修改成原始值: AThread-14 已经对原始值进行了修改,此时值为: B

You can see that the threads in the concurrency Thread-12 have successfully modified A to B, the other threads Thread-20 Change B to a at some point, and the threads in the concurrency Thread-14 can successfully change A to B again, although the end result is B, but halfway through the process of being modified, in some cases it is caused

Solution Solutions

Java AtomicStampedReference is provided to solve this problem, it is based on a version or a state, in the process of modifying not only the ratio, but also compare the version number

 Public classAabproresolve {Private Static FinalRandom random =NewRandom (); Private Static FinalString B = "B"; Private Static FinalString a = "a"; Private Static FinalAtomicstampedreference<string> atomic_stamped_reference =NewAtomicstampedreference<> (a,0);  Public Static voidMain (string[] args)throwsinterruptedexception {FinalCountdownlatch Startlatch =NewCountdownlatch (1); thread[] Threads=NewThread[20];  for(inti=0; I < 20; i++) {Threads[i]=NewThread () {@Override Public voidrun () {String OldValue=atomic_stamped_reference.getreference (); intStamp =Atomic_stamped_reference.getstamp (); Try{startlatch.await (); } Catch(interruptedexception e) {e.printstacktrace (); }                    Try{thread.sleep (Random.nextint ()& 500); } Catch(interruptedexception e) {e.printstacktrace (); }                    if(Atomic_stamped_reference.compareandset (OldValue, B, Stamp, stamp+1) {System.out.println (Thread.CurrentThread (). GetName ()+ "The original value:" +oldvalue+ "has been modified, the value is:" +atomic_stamped_reference.getreference ());            }                }            };        Threads[i].start (); } thread.sleep (200);        Startlatch.countdown (); NewThread () {@Override Public voidrun () {Try{thread.sleep (Random.nextint ()& 200); } Catch(interruptedexception e) {e.printstacktrace (); }                intStamp =Atomic_stamped_reference.getstamp (); String Oldval=atomic_stamped_reference.getreference ();  while(!Atomic_stamped_reference.compareandset (B, A,stamp, Stamp+1) ) {Stamp=Atomic_stamped_reference.getstamp (); } System.out.println (Thread.CurrentThread (). GetName ()+ "The value" +oldval+ "has been modified to the original value: A");    }}.start (); }}

Results:

Thread-1 已经对原始值: A 进行了修改,此时值为: BThread-20 已经将值 B 修改成原始值: A

You can see that threads in a concurrent period only Thread-1 modify a to ensure that only one thread modifies the data, and that other threads after a short period of concurrency Thread-20 have no effect on their modifications.

Optimization scheme, you can refer to:

78797203

Java concurrent programming principle and Combat 43: ABA Problem----CAS

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.