(Wen Shao, author of this article, first published in the blog Park. For more information, see)
From JDK 1.5, the util. concurrent package provides the Atomic type, including AtomicInteger, AtomicLong, AtomicBoolean, AtomicReference, and AtomicFieldUpdate. These classes play a major role in concurrent programming.
I thought that the Atomic in JDK was implemented in Windows by calling the InterLockedXXX series functions in <windows. h>, but later I checked the JDK source code and found that it was different from what I previously imagined. In the implementation of JVM, an Atomic class is encapsulated, and different operating systems have different implementations, for example, in the JDK 1.6 source code hotspot \ src \ OS _cpu \ win32_i1_\ vm \ atomic_win32_i486.inline.hpp file:
Inline jlong Atomic: cmpxchg (jlong exchange_value, volatile jlong * dest, jlong compare_value ){
Int mp = OS: is_MP ();
Jint ex_lo = (jint) exchange_value;
Jint ex_hi = * (jint *) & exchange_value) + 1 );
Jint cmp_lo = (jint) compare_value;
Jint cmp_hi = * (jint *) & compare_value) + 1 );
_ Asm {
Push ebx
Push edi
Mov eax, cmp_lo
Mov edx, cmp_hi
Mov edi, dest
Mov ebx, ex_lo
Mov ecx, ex_hi
LOCK_IF_MP (mp)
Cmpxchg8b qword ptr [edi]
Pop edi
Pop ebx
}
}
C # also provides the same capabilities. System. Threading. Interlocked encapsulates
InterlockedXXX series functions can implement the same functions, but the direct use of InterLocked is not as convenient as the Atomic series objects in Java.
After learning about AtomicXXX in Java and InterLockedXXX series functions in. NET, it is easy to re-implement Java AtomicXXX series objects on C. For example, AtomicInteger:
Public class AtomicInteger
{
Private int value;
Public AtomicInteger (int initialValue)
{
Value = initialValue;
}
Public AtomicInteger ()
: This (0)
{
}
Public int Get ()
{
Return value;
}
Public void Set (int newValue)
{
Value = newValue;
}
Public int GetAndSet (int newValue)
{
For (;;)
{
Int current = Get ();
If (CompareAndSet (current, newValue ))
Return current;
}
}
Public bool CompareAndSet (int unique CT, int update)
{
Return Interlocked. CompareExchange (ref value, update, reverse CT) = reverse CT;
}
Public int GetAndIncrement ()
{
For (;;)
{
Int current = Get ();
Int next = current + 1;
If (CompareAndSet (current, next ))
Return current;
}
}
Public int GetAndDecrement ()
{
For (;;)
{
Int current = Get ();
Int next = current-1;
If (CompareAndSet (current, next ))
Return current;
}
}
Public int GetAndAdd (int delta)
{
For (;;)
{
Int current = Get ();
Int next = current + delta;
If (CompareAndSet (current, next ))
Return current;
}
}
Public int IncrementAndGet ()
{
For (;;)
{
Int current = Get ();
Int next = current + 1;
If (CompareAndSet (current, next ))
Return next;
}
}
Public int DecrementAndGet ()
{
For (;;)
{
Int current = Get ();
Int next = current-1;
If (CompareAndSet (current, next ))
Return next;
}
}
Public int AddAndGet (int delta)
{
For (;;)
{
Int current = Get ();
Int next = current + delta;
If (CompareAndSet (current, next ))
Return next;
}
}
Public override String ToString ()
{
Return Convert. ToString (Get ());
}
}
After encapsulation, it is easier to directly use AtomicInteger than InterLocked, and the code will be more intuitive and elegant!
(Wen Shao, author of this article, first published in the blog Park. For more information, see)