原子性与原子变量

我们先来看看一段代码:

public class TestAtomicDemo {

    public static void main(String[] args) {
        AtomicDemo ad = new AtomicDemo();
        
        for (int i = 0; i < 9; i++) {
            new Thread(ad).start();
        }
    }
    
}

class AtomicDemo implements Runnable{
    
    private volatile int i = 0;
    
    @Override
    public void run() {
        
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
        }
        
        System.out.println(getI());
    }
    
    public int getI(){
        return i++;
    }
    
    
}

输出:

 

问题所在:多个线程去调用getI() 方法,即便volatile修饰了变量i,但是,由于volatile不能保证互斥性,每个线程可能同时读取数据,读到的i可能相同,那么会导致数据重复读取的问题。进而每个线程对i进行i++操作,得出的结果可能是相同的值。

这也就是原子性问题。

 

原子变量:在 java.util.concurrent.atomic 包下提供了一些原子变量。

1. 变量都是用volatile修饰的, 保证内存可见性

2. CAS(Compare-And-Swap) 算法保证数据变量的原子性

修改代码如下:

class AtomicDemo implements Runnable{
	
	
	private AtomicInteger i = new AtomicInteger(0);

	@Override
	public void run() {
		
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
		}
		
		System.out.println(getI());
	}
	
	public int getI(){
		return i.getAndIncrement();
	}
	
	
}

  使用原子变量,可以解决多线程原子操作问题。

 

posted @ 2017-10-30 18:13  myJavaCareerLife  阅读(415)  评论(0)    收藏  举报