In layman's Java Concurrency (2): Atomic Operation Part 1

Source: Internet
Author: User

Ext.: http://www.blogjava.net/xylz/archive/2010/07/01/324988.html

Start with a relatively simple atomic (Java.util.concurrent is a queue-based contract and the queue, in many cases, uses the atomic operation, so begin here first). In many cases we just need a simple, efficient, thread-safe increment-decrement scheme. Note that there are three conditions: simple, which means that it is easier for programmers to operate the underlying or implement as little as possible, and that efficiency means less resource consumption, faster process processing, and thread safety, which guarantees the correctness of the data in multiple threads. These three conditions look relatively simple, but they are difficult to achieve satisfactorily.

Typically, in Java, ++i or-I are not thread-safe, there are three separate operations: either the current value of the variable, the value +1/-1, and the new value is written back. In the case where no additional resources are available, only the lock can be used to guarantee the read-change-write "atomicity" of the three operations.

Doug Lea was implemented in pure Java before merging backport-util-concurrent into JSR 166, and the Synchronized keyword was inevitably used.

Public final synchronized void set (int newvalue);

Public final synchronized int getandset (int newvalue);

Public final synchronized int incrementandget ();

At the same time, volatile is used on the variable (which is exactly what the volatile is) to ensure that the get () is not locked. Although the cost of synchronized is still high, the pure Java language cannot do this without the JNI means.

After the JSR 166 was put on the agenda, Backport-util-concurrent merged into JDK 5.0, where the features of modern CPUs were reused to reduce lock consumption. These principles and features are met in the final summary of this chapter. Let's look at the use of the API before this.

Everything starts with the Java.util.concurrent.atomic.AtomicInteger.

int addandget (int delta)
Adds the given value in atomic form to the current value. is actually an I-=i+delta operation that is equal to the thread-safe version.

Boolean compareandset (int expect, int update)
If the current value = = expected value, the value is atomically set to the given update value. Returns true if successful, otherwise false, and does not modify the original value.

int Decrementandget ()
atomically subtract the current value by 1. Equivalent to the thread-safe version of the-I operation.

int get ()
Gets the current value.

int getandadd (int delta)
Adds the given value in atomic form to the current value. Equivalent to a thread-safe version of T=i;i+=delta;return T;

int Getanddecrement ()
atomically subtract the current value by 1. Equivalent to a thread-safe version of the i--operation.

int Getandincrement ()
Atomically adds 1 to the current value. Equivalent to a thread-safe version of the i++ operation.

int getandset (int newvalue)
Atomically sets the given value and returns the old value. Equivalent to a thread-safe version of T=i;i=newvalue;return T;

int Incrementandget ()
Atomically adds 1 to the current value. Equivalent to a thread-safe version of the ++i operation.

void Lazyset (int newvalue)
Finally set to the given value. The delay sets the value of the variable, which is equivalent to the set () method, but because the field is volatile, the modification of the field will have a slight performance delay (albeit negligible) than the normal field (non-volatile field), so if you do not want to read the new value of the setting immediately, allow the "background" This method is useful if you modify the value. If it is still difficult to understand, it is similar to starting a background thread, such as performing a task to modify the new value, the original thread does not wait for the result of the modification to return immediately (this explanation is actually incorrect, but it is understood).

void set (int newvalue)
Set to the given value. Modifies the original value directly, that is, the i=newvalue operation.

Boolean weakcompareandset (int expect, int update)
If the current value = = expected value, the setting is atomically set to the given update value. The JSR specification reads and conditionally writes variables but does not create any happen-before sort, and therefore does not provide a weakcompareandset Any guarantees related to previous or subsequent read or write operations of any variables outside the target. The main idea is that when calling Weakcompareandset, there is no guarantee that no happen-before will occur (that is, there may be a command reordering that causes this operation to fail). However, from the Java source, in fact, this method does not implement the requirements of the JSR specification, the final effect and compareandset are equivalent, all call the Unsafe.compareandswapint () to complete the operation.


The following code is a test sample, in order to save trouble is written in a method inside.

Package xylz.study.concurrency.atomic;

Import Java.util.concurrent.atomic.AtomicInteger;

Import Org.junit.Test;

Import static org.junit.assert.*;

public class Atomicintegertest{

@Test
public void Testall () throws Interruptedexception{
Final Atomicinteger value = new Atomicinteger (10);
Assertequals (Value.compareandset (1, 2), false);
Assertequals (Value.get (), 10);
Asserttrue (Value.compareandset (10, 3));
Assertequals (Value.get (), 3);
Value.set (0);
//
Assertequals (Value.incrementandget (), 1);
Assertequals (Value.getandadd (2), 1);
Assertequals (Value.getandset (5), 3);
Assertequals (Value.get (), 5);
//
Final int threadsize = 10;
thread[] ts = new Thread[threadsize];
for (int i = 0; i < threadsize; i++){
Ts[i] = new Thread (){
public void Run (){
Value.incrementandget ();
}
};
}
//
for (Thread t:ts){
             t.start ();
        }
        for (thread t:ts)  {
            t.join ();
        }
        //
        assertequals (Value.get (),  5+threadsize);
    }

}


As the example here is relatively simple, here is not too much to introduce.
Atomicinteger and Atomiclong, Atomicboolean, Atomicreference almost, here is not introduced. In the next article, we introduce atomic operations for arrays, fields, and other aspects.
Resources:
(1) http://stackoverflow.com/questions/2443239/ Java-atomicinteger-what-are-the-differences-between-compareandset-and-weakcompar
(2) Http://stackoverflow.com/questions/1468007/atomicinteger-lazyset-and-set

In layman's Java Concurrency (2): Atomic Operation Part 1

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.