Talking about the problem and avoidance of ABA in Java, and talking about avoiding Java ABA

Source: Internet
Author: User

Talking about the problem and avoidance of ABA in Java, and talking about avoiding Java ABA

This article mainly studies the ABA problem in Java and the related content to avoid, specifically as follows.

In Chapter 15th of Java concurrency practice, there is a concurrency stack implemented using atomic variables. The Code is as follows:

public class Node {public final String item;public Node next;public Node(String item){this.item = item;}}
public class ConcurrentStack {AtomicReference<Node> top = new AtomicReference<Node>();public void push(String item){Node newTop = new Node(item);Node oldTop;do{oldTop = top.get();newTop.next = oldTop;}while(!top.compareAndSet(oldTop, newTop));}public String pop(){Node newTop;Node oldTop;do{oldTop = top.get();if(oldTop == null){return null;}newTop = oldTop.next;}while(!top.compareAndSet(oldTop, newTop));return oldTop.item;}}

This example will not cause the ABA problem. As for why not, I will explain it later. Next I will explain the ABA problem first.

What is ABA?

Reference: If the node in the algorithm can be used cyclically, this problem may occur when the "compare and exchange" command is used, in the CAS operation, will the "V" value still be? ", In addition, if yes, the update operation is continued. In some algorithms, if the value of V changes from A to B and then from B to A, the CAS operation is successful.

Example of ABA

Sometimes, the consequences of ABA are very serious. Let's modify the example of the concurrent stack to see what problems ABA will cause:

public class Node {public final String item;public Node next;public Node(String item){this.item = item;}}
public class ConcurrentStack {AtomicReference<Node> top = new AtomicReference<Node>();public void push(Node node){Node oldTop;do{oldTop = top.get();node.next = oldTop;}while(!top.compareAndSet(oldTop, node));}public Node pop(int time){Node newTop;Node oldTop;do{oldTop = top.get();if(oldTop == null){return null;}newTop = oldTop.next;TimeUnit.SECONDS.sleep(time);}while(!top.compareAndSet(oldTop, newTop));return oldTop;}}

Note the changes here. The Node is basically unchanged.

Focus on changes to ConcurrentStack

1. push method: It used to construct a Node using the content, and now it is passed into the Node directly. This meets the requirement that "nodes in the algorithm can be used cyclically ".

2. sleep of the pop method, which is used to simulate thread execution so as to observe the results

We first press two nodes into the stack:

ConcurrentStack stack = new ConcurrentStack(); stack.push(new Node("A")); stack.push(new Node("B")); 

Create two threads to execute the operations on the stack.

Thread A executes the output stack first: Let NodeA exit the stack

stack.pop(3); 

For some reason, thread A has been running the stack for A long time and uses 3 s

Thread B executes the stack and re-enters the stack: first, NodeA and NodeB exit the stack, and then NodeD, NodeC, and NodeA are put into the stack (NodeA is at the top of the stack)

Node A = stack.pop(0); stack.pop(0); stack.push(new Node("D")); stack.push(new Node("C")); stack.push(A); 

Note: thread B implements Node recycling. It first writes all the content in the stack out of the stack, and then enters the stack. The content at the top of the stack is the Node of the previous stack.

After thread B executes these actions, thread A executes CAS. At this time, CAS can be successfully executed.

According to the original idea, after threads A and B are executed, the stack content should be: C, D, and C at the top of the Stack, but the execution result here is nothing in the stack, this is the ABA problem.

How to Avoid ABA Problems

Java provides AtomicStampedReference and AtomicMarkableReference to solve the ABA problem.

AtomicStampedReference can update two values by Atom: Reference and version number. The version number is used to differentiate the cyclic usage of nodes. The following is an example of AtomicStampedReference:

public class ConcurrentStack {AtomicStampedReference<Node> top = new AtomicStampedReference<Node>(null,0);public void push(Node node){Node oldTop;int v;do{v=top.getStamp();oldTop = top.getReference();node.next = oldTop;}while(!top.compareAndSet(oldTop, node,v,v+1));//   }while(!top.compareAndSet(oldTop, node,top.getStamp(),top.getStamp()+1));}public Node pop(int time){Node newTop;Node oldTop;int v;do{v=top.getStamp();oldTop = top.getReference();if(oldTop == null){return null;}newTop = oldTop.next;try {TimeUnit.SECONDS.sleep(time);}catch (InterruptedException e) {e.printStackTrace();}}while(!top.compareAndSet(oldTop, newTop,v,v+1));//   }while(!top.compareAndSet(oldTop, newTop,top.getStamp(),top.getStamp())); return oldTop;}public void get(){Node node = top.getReference();while(node!=null){System.out.println(node.getItem());node = node.getNode();}}}

Note: you cannot use the annotation method. Otherwise, it is no different from simply using atomic variables.

AtomicMarkableReference can update a Boolean tag bit and reference type by Atom. See the following example:

AtomicMarkableReference<Node> top = new AtomicMarkableReference<Node>(null,true);public void push(Node node){Node oldTop;Boolean v;do{v=top.isMarked();oldTop = top.getReference();node.next = oldTop;}while(!top.compareAndSet(oldTop, node,v,!v));}

Summary

The above is all the content about the ABA problem and avoidance in Java, and I hope to help you. If you are interested, you can continue to refer to other related topics on this site. If you have any shortcomings, please leave a message. Thank you for your support!

Related Article

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.