问:下面程序的运行结果是什么?
int count =0;
for(int i&#61;0; i<100; i&#43;&#43;) {
count &#61; count&#43;&#43;;
}
System.out.println("count&#61;" &#43; count);
答&#xff1a;运行结果是 count &#61; 0。
首先 count&#43;&#43; 是一个有返回值的表达式&#xff0c;返回值是 count 自加前的值&#xff0c;Java 对自加处理的流程是先把 count 的值&#xff08;不是引用&#xff09;拷贝到一个临时变量区&#xff0c;然后对 count 变量加1&#xff0c;接着返回临时变量区的值。
所以上面代码块中第一次循环的执行步骤是 JVM 把 count 值&#xff08;0&#xff09;拷贝到临时变量区&#xff0c;然后 count 值加 1&#xff0c;这时 count 的值是 1&#xff0c;接着返回临时变量区的值&#xff08;值是 0&#xff09;&#xff0c;最后返回值赋值给 count&#xff0c;此时 count 值被重置成 0&#xff1b;所以上面代码语句 count &#61; count&#43;&#43;; 可以按照如下代码来理解&#xff1a;
int autoAdd(int count) {
int temp &#61; count;
count &#61; count &#43; 1;
return temp;
}
所以第一次循环后 count 的值还是 0&#xff0c;其他 99 次的循环也是一样的&#xff0c;最终导致 count 的值始终没有改变&#xff0c;仍然保持着最初的状态&#xff1b;如果想要打印结果为 100 则需要修改 count &#61; count&#43;&#43;; 语句为 count&#43;&#43;; 即可。因此对于 &#43;&#43;/-- 运算在 java 中一定要警惕这个陷阱&#xff08;-- 运算符也一样存在这个问题&#xff09;&#xff0c;不过这个问题在不同的语言环境中的实现是不同的&#xff0c;在 C&#43;&#43; 中 count &#61; count&#43;&#43;; 与 count&#43;&#43; 是等效的&#xff0c;而在 java 等语言中 count &#61; count&#43;&#43;; 与 count&#43;&#43; 是不等效的&#xff0c;区别如这道题。
问&#xff1a;Java 或者 Android 开发中可以通过哪些方式来保证并发安全的自增自减操作&#xff1f;
答&#xff1a;java 默认的自增自减运算符是非并发安全的&#xff0c;要想实现并发安全的自增自减操作可以通过如下几种方式实现。
通过 synchronized 代码块或者方法来保证自增自减并发安全。
通过主动使用 Lock 锁来保证自增自减并发安全。
通过 JDK 提供的 AtomicInteger 类来直接保证自增自减并发安全。
上面几种做法中最推荐直接使用 AtomicInteger 的方式&#xff0c;因为其相对于其他几种方式封装性非常便捷&#xff0c;此外其实现基于 volatile 对象的 CAS 操作来保证并发安全&#xff0c;算是一种相对高效的方式。