Atomic from JDK5, the Java.util.concurrent package offers a number of classes for concurrent programming. Using these classes will have better performance on multi-core CPU machines .
The main reason is that most of these classes use optimistic locks (failure-retry mode) instead of pessimistic locks in synchronized mode.
tracked the implementation of Atomicinteger's incrementandget. Just take a note to make it easier to study later.
1. Implementation of Incrementandget
Public Final int Incrementandget () { for (;;) { int current = get (); int Next = current + 1; if (Compareandset (current, next)) return next; } }
First you can see that he is through an infinite loop (spin) until increment succeeds.
The content of the loop is
1. Get the current value
2. Calculate the value after +1
3. If the current value is still valid (not being), set the value after the +1
4. If the setting is unsuccessful (the current value is invalid, it is changed by another thread), starting with 1.
2. Implementation of Compareandset
Public Final boolean compareandset (intint update) { return Unsafe.compareandswapint (This, Valueoffset, expect, update); }
The Compareandswapint method of the unsafe class is called directly.
Full name is Sun.misc.Unsafe. This class is an implementation provided by Oracle (Sun). That's not the class in the other company's JDK .
3. Implementation of Compareandswapint
/** * atomically update Java variable to <tt>x</tt> if it is currently * Holding <TT>EXPECTED&L T;/tt>. @return <tt>true</tt> If successful */ Public Final native Boolean Long Offset, int expected, int x);
As you can see, it is not implemented in Java, but the native program of the operating system is invoked through JNI.
4. Compareandswapint's native implementation If you download the source code of OPENJDK, you can find it in the hotspot\src\share\vm\prims\ directory Unsafe.cpp
unsafe , Jobject obj, jlong offset, jint E, Jint x)) Unsafewrapper ("unsafe_compareandswapint"); = jnihandles::resolve (obj); Jint* addr = (Jint *) Index_oop_from_field_offset_long (P, offset); return (Jint) (Atomic::cmpxchg (x, addr, e)) = = E; Unsafe_end
You can see the Cmpxchg method that actually calls the atomic class.
5. Atomic's Cmpxchg
The implementation of this class is related to the operating system, which is also related to the CPU architecture, if it is the architecture of x86 under Windows
Implemented in the Atomic_windows_x86.inline.hpp file of the hotspot\src\os_cpu\windows_x86\vm\ directory
Inline Jint atomic::cmpxchg (jint volatile jint* dest, Jint compare_value) { // Alternative for InterlockedCompareExchange int MP = os::is_mp (); __asm { mov edx, dest mov ecx, exchange_value mov eax, compare_value lock_if_mp (MP) Cmpxchg DWORD ptr [edx], ecx }}
Here you can see the implementation of the embedded assembly, the key CPU instruction is CMPXCHG
There's no way to find the code down here. This means that the atomic nature of CAS is actually CPU-implemented. In fact, there is an exclusive lock on this point. The exclusive time is much shorter than the synchronized. So the performance will be better in multithreaded situations.
in the code, there's a Alternative for InterlockedCompareExchange
this InterlockedCompareExchange is a function of WINAPI, and the same thing is done in this Assembly .
Http://msdn.microsoft.com/en-us/library/windows/desktop/ms683560%28v=vs.85%29.aspx
6. Finally, x86 the CMPXCHG designation
Opcode CMPXCHG
cpu:i486+
Type of Instruction:user
Instruction:cmpxchg dest, SRC
Description:compares the accumulator with Dest. If equal the "dest"
is loaded with "src", otherwise the accumulator is loaded
With "Dest".
Flags Affected:af, CF, OF, PF, SF, ZF
CPU MODE:RM,PM,VM,SMM
+++++++++++++++++++++++
Clocks:
CMPXCHG Reg, Reg6
CMPXCHG Mem, Reg7 (if compartion fails)
Source Address: http://www.blogjava.net/mstar/archive/2013/04/24/398351.html
A brief analysis of CAS algorithm in Java