Java Concurrency (ii)--J.U.C Atomic package source Interpretation

Source: Internet
Author: User
Tags cas throw exception

The Java.util.concurrent package (J.U.C) after Java5 is the work of the world-class concurrent Master Doug Lea, which mainly implements

    1. The corresponding atomic class of Integer/long in atomic package is mainly based on CAS;
    2. Some of the same steps, including Lock,countdownlatch,semaphore,futuretask, are based on the Abstractqueuedsynchronizer class;
    3. About the executors class of thread execution, etc.;
    4. Some concurrent collection classes, such as Concurrenthashmap,concurrentlinkedqueue,copyonwritearraylist.
      Today we mainly introduce the content under the atomic package.
Cas

The classes under the atomic package are based primarily on a directive supported by the modern mainstream CPU, Compare and Swap (CAS), which can provide better performance for multithreaded programming. Refer to a section of Java Concurrency in practice for a description:

Here, CAS refers to a special instruction that is widely supported by modern CPUs in the operation of shared data in memory. This instruction will perform atomic read and write operations on the shared data in memory. Briefly describe the operation of this instruction: first, the CPU compares the data that will be changed in memory with the expected value. Then, when the two values are equal, the CPU replaces the values in memory with the new values. Otherwise, do not do the operation. Finally, the CPU returns the old value. This series of operations is atomic. Although seemingly complex, they are the root of the Java 5 concurrency mechanism, which is superior to the original locking mechanism. Simply put, the meaning of CAS is "What I think the original value should be, if it is, update the original value to a new value, otherwise do not modify, and tell me what the original value is."

Atomicinteger
private volatile int value;

The Atomicinteger contains only one field, which is used to record the current value and is defined as volatile to satisfy the visibility .

Setup to use Unsafe.compareandswapint for updates    private static final unsafe unsafe = Unsafe.getunsafe ();    Private static final long valueoffset;    static {      try {        valueoffset = Unsafe.objectfieldoffset            (AtomicInteger.class.getDeclaredField ("value"));      } catch (Exception ex) {throw new Error (ex);}    }

The static variable is defined in the beginning Unsafe,atomicinteger the method inside the unsafe

Public Final native Boolean compareandswapint (Object var1, long var2, int var4, int var5);

The encapsulation of the method.
Let's look at the atomic i++,

Public final int getandincrement () {for        (;;) {            int current = Get ();            int next = current + 1;            if (Compareandset (current, next))                return to current;        }    }

Inside an infinite loop, first gets the current value and then calls the

Public final Boolean compareandset (int expect, int. update) {    return unsafe.compareandswapint (this, Valueoffset, expect, update);    }

The meaning of Unsafe.compareandswapint (this, valueoffset, expect, update) is to compare the Valueoffset in this object (that is, value) with expect, if equal, is modified to update, returns True, or, if not equal, indicates that another thread has modified value after getting to current, and then re-repeated until the modification succeeds. As can be seen here, theoretically, this method is likely to never return, in fact, when the concurrency conflict is very serious, repeated compareandset (current, next) failure, it may also take a lot of time.
The other methods inside the Atomicinteger are basically similar; other classes include atomiclong,atomicreference, which is also the basic compareandset of the unsafe inside the package.

Unsafe

The importance of unsafe classes in implementing atomic can be seen earlier. Why is there unsafe this class, the basic reason is that Java does not allow code to directly manipulate memory, the benefit is more secure, generally do not have a memory leak, because there is a JVM GC, the downside is that some of the underlying calls can not be executed. My understanding is, unsafe is this Java security siege to such as C + + This unsafe periphery of a door, so called unsafe. Unsafe is basically the native, that is, through the JNI call C + + code. Most are direct memory operations, as well as the pending wake-up threads that will be discussed later, including Park and Unpark.
Front to

Public Final native Boolean compareandswapint (Object var1, long var2, int var4, int var5);

It is not Java code, if you want to see the implementation, you need to download OPENJDK source code, which is the C + + code call assembly, BlaBla. I do not recommend that you continue down, for several reasons, one is that we use the Java and other high-level language purpose is to avoid tangled complex underlying details, standing in the higher level of thinking about the problem, but there are more problems in Java waiting for you to solve, more knowledge can learn! If you say that you have completely mastered Java, including the JDK source code, tomcat, spring,xxxxx source code have seen, really did not see, then I will say, more accompany with family Bar ~ unless you are the JVM development engineer, OH, that embarrassed, big God, when I did not say anything .... For completeness, I post several reference links http://www.blogjava.net/mstar/archive/2013/04/24/398351.html, http://zl198751.iteye.com/blog/1848575.
What if we get unsafe? Unsafe has a static method to obtain an unsafe instance, as follows

public static Unsafe Getunsafe () {        Class var0 = Reflection.getcallerclass (2);        if (var0.getclassloader () = null) {            throw new SecurityException ("Unsafe");        } else {            return theunsafe;        }    }

But if you use in your own code, you can compile the pass, but the runtime error. Because the inside of the class that restricts the call to Getunsafe () This method must be the startup ClassLoader Bootstrap Loader. So if you want to call unsafe in your own code (it is strongly recommended not to do this), you can use the Java reflection to achieve:

Static class Unsafesupport {        private static unsafe unsafe;        Static {            field field;            try {                //information obtained by the anti-compilation Unsafe class                field = Unsafe.class.getDeclaredField ("Theunsafe");                Field.setaccessible (true);                Gets the static property that unsafe = (unsafe) Field.get (null) is loaded with Rt.jar when the JVM is started, and the            catch (Exception e) {                E.printstacktrace ();            }        }        public static unsafe getinstance () {//            return Unsafe.getunsafe ();//no use, only native get, otherwise will throw exception            return Unsafe;        }    }

After obtaining an instance of unsafe, you can still implement the atomic class yourself, and again, it is highly recommended not to do so!!!

CAS Benefits

Compare and Set is a non-blocking algorithm, which is its advantage. Because of the CPU-supported instructions, it provides better performance and scalability than the original concurrency mechanism. You can think of better performance in general and easier to use (that's the point).

CAs consABA Issues

CAS operations can lead to ABA problems, that is, between doing a++, a may be modified by multiple threads, but back to the original value, then CAs will think that the value of a does not change. A in the outside stroll around a circle back, you can guarantee that it did not do anything bad, can't!! Perhaps it is idle, the value of B minus a bit, the value of C and so on, and so on, even if a is an object, this object may be newly created, A is a reference to the situation, so there are still a lot of problems, there are many ways to solve the ABA problem, You can consider adding a change count (version number), only if the change count is constant and the value of a does not change, the a++,atomic package has the Atomicstampedreference class to do this thing, which is a bit similar to transactional atomicity!

Long cycle times cost large
    1. Even without any contention, you will do some useless work.
    2. If the conflict is serious, it may cause multiple modifications to fail, the for cycle time is long, and may be slower than synchronization
      I use 100 threads on my own computer to modify a shared variable and find that using Atomicinteger is slower than synchronized, but it's fast! So still the proposal, do not be premature optimization, do not tangle in the end is 1ms or 2ms, unless the test is found to be a performance bottleneck, and then take a closer look, is not the use of code problems, to believe that can write to the JDK code, generally there is no problem. Generally less than a day tens of millions of billion of PV, should be no problem. And the JVM has done a lot of optimizations for synchronized, including lock elimination, lightweight locks, biased locks, etc., so the first thing to write code is to consider the code to be correct, clear, and maintainable. only the atomic operation of a shared variable can be guaranteed if the concurrency constraint involves two variables, it is not possible to use two atomic variables to achieve the overall atomicity, or to use synchronization. Of course, you can also use a workaround to define a class that contains the variables involved in the constraints, and then use Atomicreference to achieve atomicity. summarizing the analogy of the atomic package, such as Atomicinteger, is mainly based on CAS instructions supported by modern mainstream CPUs, which are called through the native method of the unsafe class. In general, performance is better than lock synchronization, but it's good enough to generally not run into performance issues, whether it's semantically satisfying usage requirements, and whether it can make the code fresher.

Refers

    1. http://my.oschina.net/lifany/blog/133513
    2. http://zl198751.iteye.com/blog/1848575
    3. http://blog.csdn.net/aesop_wubo/article/details/7537960
    4. http://my.oschina.net/u/177808/blog/166819
    5. Http://www.blogjava.net/mstar/archive/2013/04/24/398351.html
    6. http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/
    7. http://zeroturnaround.com/rebellabs/dangerous-code-how-to-be-unsafe-with-java-classes-objects-in-memory/
    8. Http://www.pwendell.com/2012/08/13/java-lock-free-deepdive.html

Java Concurrency (ii)--J.U.C Atomic package source Interpretation

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.