在上一节java开发:乐观锁CAS机制中我们说过CAS机制的原理,与及使用CAS会发生的ABA问题解决办法。
java中提供一些列的基本数据类型原子操作类用来实现操作基本数据类型时保证线程安全,其底层就是使用CAS机制实现的。AtomicInteger
则是用来操作int类型的数据,保证线程安全。
什么是ABA问题呢?举个例子:比如说我的卡里有100大洋,此时有俩个线程同时去操作这100大洋,它们拿到的副本都是100。若线程2被阻塞了,线程1执行任务扣掉了50大洋,现在卡里剩50。正好我妈(线程3)此时刚好打给我50大洋,现在卡里的钱又变回了100。当线程2被唤醒后也执行扣款操作,扣掉50大洋,当它准备提交数据时比较旧的预期值和共享内存的实际值发现都是100,因此线程2也扣款成功,卡里只剩50大洋。。。想想就不对劲啊,我本来有100,我妈打给我50,我就取了50。不应该是剩100吗?这不害我白白损失了50大洋吗
final AtomicInteger atomicInteger = new AtomicInteger(100);
ExecutorService service = Executors.newCachedThreadPool();
service.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
//获取最新的值
int result = atomicInteger.get();
System.out.println("线程1预期值"+result);
//休眠五秒
Thread.sleep(5000);
//修改共享变量,减去50
atomicInteger.addAndGet(-50);
System.out.println("线程1新值"+atomicInteger.get() );
return null;
}
});
service.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
//获取最新的值
int result = atomicInteger.get()