• Java util.concurrent包AtomicXXX系列对象在C#中的实现


    (本文作者温少,首发于博客园,转载请注明)

    从JDK 1.5开始,util.concurrent包提供了Atomic类型,包括AtomicInteger、AtomicLong、AtomicBoolean、AtomicReference、AtomicFieldUpdate等,这些类在并发编程中大有作用。

    我原先以为JDK中的Atomic在Windows下实现是调用<windows.h>中InterLockedXXX系列函数实现的,但后来查看了JDK的源码,发现和原先想像中的不一样。JVM的实现中,封装了一个Atomic的类,然后不同的操作系统有不同的实现,例如,在JDK 1.6源码hotspot\src\os_cpu\win32_i486\vm\atomic_win32_i486.inline.hpp文件中:

    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#也提供了同样的能力,System.Threading.Interlocked封装了<windows.h>中的 InterlockedXXX系列函数,可以实现同样的功能,但是直接使用InterLocked没有象Java中的Atomic系列对象方便。

    了解清楚Java中的AtomicXXX和.NET中InterLockedXXX系列函数之后,把Java的AtomicXXX系列对象在C#上重新实现一遍是很容易的事情。例如实现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 expect, int update)
        {
            
    return Interlocked.CompareExchange(ref value, update, expect) == expect;
        }

        
    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());
        }
    }

    封装过之后,直接使用AtomicInteger比使用InterLocked更方便,代码也会更直观优美!

    (本文作者温少,首发于博客园,转载请注明)

  • 相关阅读:
    冒泡 希尔 快速 插入 堆 基数
    排序总结
    软件工程(齐治昌-谭庆平-宁洪)
    Java简单计算器
    插入排序
    Android中theme.xml与style.xml的区别
    activity theme parent 属性浅析
    xml中不能直接添加ViewGroup
    Java中对象的上转型对象
    Android原理View、ViewGroup
  • 原文地址:https://www.cnblogs.com/jobs/p/959798.html
Copyright © 2020-2023  润新知