問:下面程序的運行結果是什么?
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 操作來保證并發安全,算是一種相對高效的方式