1.实现计数器代码
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class Counter {
private AtomicInteger atomicI = new AtomicInteger(0);
private int i = 0;
public static void main(String[] args) {
final Counter cas = new Counter();
List<Thread> ts = new ArrayList<>(600);
long start = System.currentTimeMillis();
for (int j = 0; j < 100; j++) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
cas.count();
cas.safeCount();
}
}
});
ts.add(t);
}
for (Thread t : ts) {
t.start();
}
//等待所有线程执行完成
for (Thread t : ts) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("非线程安全:"+cas.i);
System.out.println("线程安全:"+cas.atomicI.get());
System.out.println(System.currentTimeMillis() - start);
}
//使用cas实现线程安全的计数器
private void safeCount(){
while (true) {
int i = atomicI.get();
boolean suc = atomicI.compareAndSet(i, ++i);
if (suc) {
break;
}
}
}
//非线程安全计数器
private void count(){
i++;
}
}
2.CAS实现原子操作存在三大问题
1.ABA问题
2.循环时间长开销大
3.只能保证一个共享变量的原子操作
3.使用锁机制实现原子操作
除了偏向锁,JVM实现锁的方式都用了循环CAS
即当一个线程想进入同步块的时候使用循环CAS的方式来获取锁,当它退出同步块的时候使用循环CAS释放锁