1. 程式人生 > >多執行緒環境下的計數器

多執行緒環境下的計數器

下面的例子是通過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可以實現安全的計數器;