在多线程环境下,实现一个CAS原理的线程安全的技术器,并与不使用CAS算法的计数器进行比较。
package com.feiyu.text;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @Created by 猎风工作室
* @Author by 飞宇
* @Date 2018/11/20 16:25
*/
public class Counter {
private AtomicInteger atomicInteger = new AtomicInteger(0);
private int i=0;
public static void main(String[] args) {
final Counter cas = new Counter();
List<Thread> threadArrayList = new ArrayList<Thread>(600);
long start = System.currentTimeMillis();
for(int j=0;j<100;j++){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<10000;i++){
cas.count();
cas.safeCount();
}
}
});
threadArrayList.add(thread);
}
for (Thread thread : threadArrayList){
thread.start();
}
/**
* 等待所有线程执行完成
*/
for (Thread thread : threadArrayList){
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(cas.i);
System.out.println(cas.atomicInteger.get());
System.out.println(System.currentTimeMillis() - start);
}
/**
* 使用CAS实现线程安全的计数器
*/
private void safeCount() {
for (;;){
int i = atomicInteger.get();
boolean suc = atomicInteger.compareAndSet(i,++i);
if (suc){
break;
}
}
}
/**
* 非线程安全的计数器
*/
private void count() {
i++;
}
}
结果如下:
我们分析可得,当在多线程环境下,为了实现原子操作,我们使用CAS。
当使用CAS时,得到的计数为正确的1000000,而未使用时,得到的却是另一个结果,因为线程是竞争得到CPU处理时间片的,所以得到的计数也是不一样的,但是却肯定比线程安全时的少。