public final int getAndIncrement() {
for (;;) {
int current = get(); // 取得AtomicInteger里存储的数值
int next = current + 1; // 加1
if (compareAndSet(current, next)) // 调用compareAndSet执行原子更新操作
return current;
}
}

  

 
我们先来看一下AtomicInteger类的getAndIncrement的源代码:
 

这段代码写的很巧妙:
         1,compareAndSet方法首先判断当前值是否等于current;
         2,如果当前值 = current ,说明AtomicInteger的值没有被其他线程修改;
         3,如果当前值 != current,说明AtomicInteger的值被其他线程修改了,这时会再次进入循环重新比较;
   
    在getAndIncrement方法中,它的做法是:先获取到当前的 value 属性值,然后将 value 加 1,赋值给一个局部的 next 变量,然而,这两步都是非线程安全的,但是内部有一个死循环,不断去做compareAndSet操作,直到成功为止,也就是修改的根本在compareAndSet方法里面。
我们可以看到在compareAndSet()方法中调用的是sun.misc.Unsafe.compareAndSwapInt(Object obj, long valueOffset, int expect, int update)方法,
compareAndSwapInt 基于的是CPU 的 CAS指令来实现的。所以基于 CAS 的操作可认为是无阻塞的,一个线程的失败或挂起不会引起其它线程也失败或挂起。并且由于 CAS 操作是 CPU 原语,所以性能比较好。

综上,getAndIncrement() 方法并不是原子操作。 只是保证了他和其他函数对 value 值得更新都是有效的。

他所利用的是基于冲突检测的乐观并发策略。 可以想象,这种乐观在线程数目非常多的情况下,失败的概率会指数型增加。

最新文章

  1. linux下mv命令使用方法
  2. 转【】浅谈sql中的in与not in,exists与not exists的区别_
  3. 使用PreparedStatement执行SQL语句时占位符(?)的用法
  4. AndroidAnnotations部署
  5. Tapestry5.3使用总结
  6. jquery指定div右键事件
  7. ELK日志收集分析系统配置
  8. vue的混合mixins学习
  9. 计算机网络实验 UDP套接字编程
  10. python:数据类型dict
  11. pair work 附加题解法(张艺 杨伊)
  12. HDU 2254 奥运(矩阵+二分等比求和)
  13. python------模块定义、导入、优化 ------->hashlib模块
  14. XSS代码注入框架
  15. Centos6下Python3的编译安装
  16. (C/C++学习笔记) 十四. 动态分配
  17. 设计模式学习——工厂模式(Factory Pattern)
  18. Linux中断 - GIC代码分析
  19. IDE、SATA、SCSI、SAS、FC、SSD 硬盘类型
  20. Tomcat 基础优化

热门文章

  1. Python Lab Assignments
  2. 实验吧——加了料的报错注入(exp报错注入)
  3. PHP生成json
  4. Linux C/C++编译过程中的各种not declared in this scope
  5. Django框架(七)-- 模板层:模板导入、模板继承、静态文件
  6. JMETER 生成测试报告
  7. Linux用户环境配置文件
  8. Qemu-4.1 桥接网络设置
  9. 给大家推荐一个nginx.conf文件格式生成的网站
  10. db.sqlite如何导出转储为sql文件