我知道i ++不是線程安全操作。我也明白爲什麼我++也比我= i + 1更快。在線程安全方面,i = i + 1與i ++有什麼不同?任何字節碼級別的解釋都會很有幫助。就原子性而言,i ++和i = i + 1之間的區別
回答
i += 1
和i++
都不是原子的(都不是線程安全的)。 ++i
也是如此。這裏有一個簡單的測試,你可以運行來證明這一點:
public class Test {
static volatile int x, y;
static class IncThread extends Thread {
public void run() {
for (int i=0; i<50000; i++) x++;
for (int i=0; i<50000; i++) y = y+1;
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new IncThread();
Thread t2 = new IncThread();
t1.start();
t2.start();
t1.join();
t2.join();
System.out.printf("x = %d, y = %d%n", x, y);
}
}
這是我得到的輸出:
x = 99897, y = 81556
顯然,一些寫的迷路了。有一個很好的小博客文章,++ not considered atomic,解釋這一點。這篇文章也指出@八月的答案是誤導性的。該字節碼(iinc
)僅用於增加局部變量,這從線程安全的角度來看並不令人感興趣。 (博客文章還討論了用於增量的不同字節碼。)
如果您在8月份的回答中遇到問題,您應該在該答案下發表評論,並且可能會降低評分。有人可能會使用這個答案,甚至沒有看到你的答案。 – 2014-12-02 04:35:27
還有就是,字節代碼明智i++
和i += 1
之間沒有差異:
增量(來源):
public static void main(String[] args) {
int i = 0;
i++;
}
增量(字節碼):
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iinc 1, 1
5: return
化合物加成(來源):
public static void main(String[] args) {
int i = 0;
i += 1;
}
化合物加成(字節碼):
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iinc 1, 1
5: return
用於遞增字段字節碼也是相同的,儘管它不使用(因爲它需要一個局部變量索引):
int x;
void inc() { x++; }
void assign() { x += 1; }
void inc();
Code:
0: aload_0
1: dup
2: getfield #2 // Field x:I
5: iconst_1
6: iadd
7: putfield #2 // Field x:I
10: return
void assign();
Code:
0: aload_0
1: dup
2: getfield #2 // Field x:I
5: iconst_1
6: iadd
7: putfield #2 // Field x:I
10: return
如何從編譯源代碼讀取字節碼? – 2014-12-02 04:16:55
@DavidJones你可以使用'javap -c Foo。(或我相當蹩腳的[網站](http://bytes.i-i.im/)) – August 2014-12-02 04:18:53
酷!謝謝... – 2014-12-02 04:19:42
在這些術語中,i ++和i = i + 1沒有區別。
請檢查這些以瞭解差異http://stackoverflow.com/a/29559727/4025692 – 2015-04-10 11:17:34
i=i+1
使用一個二元運算符(+)加載i的值,並將其加1,然後將結果存回i中。相比之下,i++
使用一元(++)運算符,它使用單個彙編指令簡單地增加該值,因此理論上它可能更高效。然而,今天的編譯器優化i=i+1
和i++
將導致相同的優化代碼。
- 1. Javascript:Forloop i ++和(i + 1)之間的區別
- 2. *(matrix1 + i)和* matrix1 [i]之間的區別?
- 3. 從任何角度來看,++ i和i + = 1之間的區別
- 4. i = i + j有什麼區別;和i + = j;在C語言?
- 5. (1 << 32)和(1 << i)之間的區別其中i == 32
- 6. Increment ++ i,i ++和i + = 1
- 7. printf(「%d」,i ++)和i ++之間有什麼區別;的printf( 「%d」,i)的?
- 8. I/O端口和I/O內存之間的區別
- 9. * x = i和x =&i之間的區別是什麼
- 10. int p = *(int *)i和int p = *(int *)&i之間的區別
- 11. 德爾福的inc(i)和i:= i + 1之間有性能差異嗎?
- 12. i-vector和d-vector之間的區別
- 13. i ++和++ i有什麼區別?
- 14. --i和i--有什麼區別?
- 15. i == 0和0 == i有區別嗎?
- 16. ++ i和i + 1在javascript中的區別是什麼
- 17. 在MATLAB中使用(j,i)與(i,j)之間的區別
- 18. C中i--和i-1有什麼區別?
- 19. 爲什麼「for($ i = 1; $ i -le 1000000; $ i ++){}」的執行時間快於「for([int] $ i = 1; $ i -le 1000000; $ i ++){}」在PowerShell中
- 20. USB標準中語法I(0,1)和I(1,0)之間的區別是什麼?
- 21. 爲什麼i = i + 1比i ++快?
- 22. 「i ++」如何比「i = i + 1」更高效?
- 23. 爲什麼人們使用i = i + 1而不是i ++?
- 24. 對於(我在數組中)和for(var i = 0; i <array.length; i ++)之間的區別
- 25. C#中++ i和i ++之間有任何性能差異嗎?
- 26. (數組中的x)和(i = 0; i <array.length; i ++)
- 27. PHP中的++ $ i和$ i ++有什麼區別?
- 28. 將i和i傳遞給函數的區別
- 29. C++ array.at(i)和array [i]的性能
- 30. Cypher:找到滿足步驟i和i之間的條件的路徑+ 1
它們編譯爲[相同的字節碼](http://pastebin.com/raw.php?i=G6Hadz8Q),所以它們應該具有相同的性能。 – August 2014-12-02 04:03:00
@ August2 - 尼斯。您應該將其作爲答案發布。 – EJK 2014-12-02 04:05:44