多線程環境下的計數器

下面的例子是通過CAS來實現一個多線程環境下的安全計數器


package cn.com.test.vol.p201612;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class Counter {

	private static AtomicInteger ai = new AtomicInteger();
	private static int i = 0;
	
	// 使用CAS實現線程安全的計數器  
	public static void safeAdd(){
		//用一個for循環,如果沒有計數成功的話,會一直執行這段代碼,知道計數成功break爲止  
		for(;;){
			int j = ai.get();	//讀取value值,賦給j,  j在線程的工作內存中  
			//將主內存中的值(current)與工作內存中的值j相比較,如果相等的話,說明工作內存中的j值仍然是value的最新值  
	        //計數運算對當前i操作沒有問題,將value值設爲j+1,因爲value是volatile的,所以寫的時候也就寫到了主內存  
			boolean b = ai.compareAndSet(j, j+1);
			if(b){	//如果+1成功
				break;
			}
		}
	}
	
	// 非安全的線程計數器  
	public static void add(){
		i = i+1;
	}
	
	public static void main(String[] args){
		ExecutorService es = Executors.newCachedThreadPool();
		for(int i=0;i<1000;i++){
			es.execute(new Runnable(){
				@Override
				public void run() {
					Counter.add();
					Counter.safeAdd();
				}
			});
		}
		System.out.println("i="+i);
		System.out.println("ai="+ai.get());
	}
	
}
運行結果:
i=997
ai=1000

運行多次,ai始終都是1000,說明通過CAS可以實現安全的計數器;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章