多线程环境下的计数器

时间:2021-10-12 14:49:15

下面的例子是通过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可以实现安全的计数器;