多线程-Atomic分析

Java.util.concurrent中提供了atomic原子包,可以实现原子操作(atomic operation),即在多线程环境中,执行的操作不会被其他线程打断。

public class AtomicDemo  
    extends Thread {  


    private static final AtomicInteger TEST_INT = new AtomicInteger();  


    @Override  
    public void run() {  
        TEST_INT.incrementAndGet();  
    }  


    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
        for (int i = 0; i < 1000; i++) {  
            AtomicDemo demo = new AtomicDemo();  
            demo.start();  
            try {  
                demo.join();  
            }  
            catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  

        System.out.println("最终结果:"+TEST_INT);  
    }  


}  

原理分析:

/** 
     * Atomically increments by one the current value. 
     * 
     * @return the updated value 
     */  
    public final int incrementAndGet() {  
        for (;;) {  
            //获取当前值value  
            int current = get();  
            int next = current + 1;  
            //循环执行到递增成功  
            if (compareAndSet(current, next))  
                return next;  
        }  
    } 

private volatile int value;

value是volatile类型,确保此线程能获取到最新值。
方法不断获取value值再进行递增操作,直至操作成功。

public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
compareAndSet使用Unsafe调用native本地方法CAS(CompareAndSet)递增数值。

CAS简要yingj
CAS利用CPU调用底层指令实现-使用硬件指令非程序命令。
单一处理器,进行简单的读写操作时,能保证自身读取的原子性,多处理器或复杂的内存操作时,CAS采用总线加锁或缓存加锁方式保证原子性。
1.总线加锁
如i=0初始化,多处理器多线程环境下进行i++操作下,处理器A和B同时读取i值到各自缓存,分别进行递增,回写值i=1相同。处理器提供LOCK#信号,进行总线加锁后,处理器A读取i值并递增,处理器B被阻塞不能读取i值。
2.缓存加锁
总线加锁,在LOCK#信号下,其他线程无法操作内存,性能较差,缓存加锁能较好处理该问题。
缓存加锁,处理器A和B同时读取i值到缓存,处理器A提前完成递增,数据立即回写到主内存,并让处理器B缓存该数据失效,处理器B需重新读取i值。

你可能感兴趣的:(Java多线程)