问题

在 int i = 0; i = i++; 语句中,i = i++是线程安全的么?如果不安全,请说明上面操作在JVM中的执行过程,为什么不安全?说出JDK中哪个类能达到以上的效果,并且是线程安全而且高效的,简述其原理。

回答

语句 i = i++;不是线程安全的。

该语句执行过程如下,

先把 i 的值取出来放到栈顶,可以理解为引入了一个第三方变量 k,此时,k的值为i,

然后执行自增操作,i的值变为1,

最后执行赋值操作 i = k (自增前的值)

因此执行结束后,i的值还是0.

从上面的分析可知,i = i++语句的执行过程有多个操作组成,不是原子操作,因此不是线程安全的。

在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而java.util.concurrent.AtomicInteger是一个提供原子操作的Integer类,其提供了线程安全且高效的原子操作,是线程安全的。

AtomicInteger类的底层实现原理是利用处理器的CAS操作(Compare And Swap,比较与交换,一种有名的无锁算法)来检测栈中的值是否被其他线程改变,如果被改变则CAS操作失败。这种实现方法在CPU指令级别实现了原子操作,因此,其比使用synchronized来实现同步效率更高。

CAS操作过程都包含三个运算符:内存地址V、期望值E、新值N。当操作的时候,如果地址V上存放的值等于期望值E,则将地址V上的值赋为新值N,否则,不做任何操作,但是要返回原值是多少。这就保证比较和设置这两个动作是原子操作。系统主要利用JNI(Java Native Interface,Java本地接口)来保证这个原子操作,它利用CPU硬件支持来完成,使用硬件提供swap和test_and_set指令,但CPU下同一指令的多个指令周期不可中断,SMP(Symmetric Multi-Processing)中通过锁总线支持这两个指令的原子性。

最新文章

  1. SVN分支研究
  2. ios swift 2 新的OptionSetType使用方法
  3. Could not load file or assembly'System.Data.SQLite.dll' or one of its depedencies
  4. arr.sort()排序方法
  5. NHibernate系列
  6. Mobile页面项目总结
  7. 项目Contact开发中遇到的,引以为戒
  8. Beta版本冲刺前准备
  9. Python的IO编程
  10. HTML5存储技术Storage
  11. (转)解决NSMutableAttributedString富文本,不同文字大小水平轴对齐问题(默认底部对齐)
  12. Java-Socket实现文件的断点续传
  13. 理解SSL、HTTPS原理中的对称加密与非对称加密
  14. Android 发送邮件以及定时发送邮件的实现
  15. vue里router-link标签设置动态路由的3个方法
  16. django xadmin
  17. AT2046 Namori 图论
  18. Iterator 与ListIterator的区别
  19. 深入分析ReentrantLock公平锁和非公平锁的区别
  20. QProcess 进程调用

热门文章

  1. css-background-image 背景图片太大或太小
  2. python list 常用
  3. 大型运输行业实战_day12_1_权限管理实现
  4. ServiceWorker.state
  5. Android学习路-Android Studio的工程目录
  6. 有关vim的一些命令
  7. POJ-3984.迷宫问题(BFS + 路径输出)
  8. 方法装饰器(Decorator)
  9. [Java学习]反射机制(待续226)
  10. Myeclipse安装完配置