Non-blocking algorithm-stack, blocking algorithm-Stack

Source: Internet
Author: User

Non-blocking algorithm-stack, blocking algorithm-Stack

In the previous section, we used counters as an example to describe non-blocking algorithms. In this section, we use a slightly more complex data structure stack to describe the practical application of non-blocking algorithms.
1. Single-thread Stack

public class SingleThreadStack  implements Stack{    private Node head;    public Node pop() {        if (head == null) {            return null;        }        Node h = head;        head = head.getNext();        h.setNext(null);        return h;    }        @Override    public void push(int value) {        Node node = new Node();        node.setValue(value);        node.setNext(head);        head = node;    }}

The stack header pops up and is set as the next node. If the stack header is empty, the stack is empty and the return value is null. Set next of the new stack node to the original stack header and set the new node to the stack header. This stack is NOT thread-safe. For example, if two threads A and B Exit the stack at the same time, there are only two elements in the stack, the elements in the stack should be popped up after two outputs, but if both threads A and B execute head = head at the same time. getNext (); this Code (the essence of this Code is to extract next first, and then assign values) it is possible that the two threads A and B only pop up and return the same element for the two stack operations. The same is true for inbound stack.

2. multi-thread synchronization Stack

public class SynchronizedStack implements Stack{    private SingleThreadStack delegate = new SingleThreadStack();    @Override    public synchronized Node pop() {        return delegate.pop();    }    @Override    public synchronized void push(int value) {        delegate.push(value);    }}

To better describe the role of synchronization, all stack operations are directly forwarded to the previous single-thread stack. We can see that both the outbound stack and the inbound Stack are synchronous serial operations, the preceding multi-threaded concurrent operations will not cause two threads to operate only one element at a time. It is actually a queue of multi-threaded concurrent operations. First, the lock is obtained first, and then the lock is obtained.

3. Lock-free algorithm Stack

Public class CasNoLockStack implements Stack {private CasNode head; @ Override public CasNode pop () {for (;) {CasNode h = head; // if (h = null) {return null;} CasNode next = h; if (head. casSet (h, next) {h. setNext (null); return h ;}}@ Override public void push (int value) {CasNode node = new CasNode (); node. setValue (value); for (;) {CasNode h = head; if (head. casSet (h, node) {node. setNext (h); return ;}}}}

For example:
When the stack is output, the stack header is first obtained by the current thread and assigned to the local variable h. If h is empty, the current stack is empty and the return value is null. Continue to get next node next of h, and then try to set the stack header to next node using the cas (h, next) method. If this method returns success, if the stack header has been successfully updated, it indicates that the h node is the latest stack header. Set the next node of h to null and return. If the returned result of this method fails, it indicates that the stack header has been modified by other threads. Then, repeat the process from the first step until it is successful, and the loop will definitely end, because the cas operation fails, it means that other threads have already performed the stack operation. In the end, either the stack is successfully exited in the current thread, or the elements in the stack Are popped up by other threads. The current thread returns null.
Next, let's talk about the inbound stack. When the inbound stack is started, create a new stack header node. After going into the loop, the first step is to obtain the current stack header and assign it to the local variable h. cas (h, node) is used) an attempt is made to assign the stack header to the new node on the stack. If the stack header is successfully modified by other threads, the current thread has successfully modified the stack header, point the next of the new stack header to the old stack header. If it fails, it indicates that other threads have modified the stack header node, you need to reloop back to the first step and continue to obtain the new stack header until the operation is successful. When the competition is very serious, it may fail multiple times and execute multiple cycles.

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.