Java陷阱

问:下面程序的运行结果是什么?

int count =0;

for(int i=0; i<100; i++) {

    count = count++;

}

System.out.println("count=" + count);

答:运行结果是 count = 0。

首先 count++ 是一个有返回值的表达式,返回值是 count 自加前的值,Java 对自加处理的流程是先把 count 的值(不是引用)拷贝到一个临时变量区,然后对 count 变量加1,接着返回临时变量区的值。

所以上面代码块中第一次循环的执行步骤是 JVM 把 count 值(0)拷贝到临时变量区,然后 count 值加 1,这时 count 的值是 1,接着返回临时变量区的值(值是 0),最后返回值赋值给 count,此时 count 值被重置成 0;所以上面代码语句 count = count++; 可以按照如下代码来理解:

int autoAdd(int count) { 

    int temp = count;

    count = count + 1; 

    return temp;

}

所以第一次循环后 count 的值还是 0,其他 99 次的循环也是一样的,最终导致 count 的值始终没有改变,仍然保持着最初的状态;如果想要打印结果为 100 则需要修改 count = count++; 语句为 count++; 即可。因此对于 ++/-- 运算在 java 中一定要警惕这个陷阱(-- 运算符也一样存在这个问题),不过这个问题在不同的语言环境中的实现是不同的,在 C++ 中 count = count++; 与 count++ 是等效的,而在 java 等语言中 count = count++; 与 count++ 是不等效的,区别如这道题。

Java

问:Java 或者 Android 开发中可以通过哪些方式来保证并发安全的自增自减操作?

答:java 默认的自增自减运算符是非并发安全的,要想实现并发安全的自增自减操作可以通过如下几种方式实现。

通过 synchronized 代码块或者方法来保证自增自减并发安全。

通过主动使用 Lock 锁来保证自增自减并发安全。

通过 JDK 提供的 AtomicInteger 类来直接保证自增自减并发安全。

上面几种做法中最推荐直接使用 AtomicInteger 的方式,因为其相对于其他几种方式封装性非常便捷,此外其实现基于 volatile 对象的 CAS 操作来保证并发安全,算是一种相对高效的方式

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 14,348评论 0 33
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,895评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,292评论 19 139
  • 文 / 平生心事 在《红楼梦》里,男人们被曹公排着队抖落,其中描写贾琏好色的片段最多。 贾琏,一个比较典型的花花公...
    平生心事阅读 5,335评论 0 4
  • 2月的最后一天 我一直都在。 今日推荐: 林俊杰,从一开始的《江南》,到后来的《编号89757》,他的声音就很有辨...
    小鹿爱生活笔记阅读 2,795评论 1 1