在java中,除了long和double的8個字節、64位比特的變量外,其他的基本變量都是原子性的。
java存儲模型要求獲取和存儲操作都為原子性,但是對于非volatile的long和double變量,jvm允許將64位的讀或寫劃分為兩個32位的操作。
如果讀和寫發生在不同的線程,這種情況讀取一個非volatile類型long就可能會出現得到一個值的高32位和另一個值的低32位。
因此,即使你并不關心過期數據,但僅僅在多線程程序中使用共享的、可變的long和double變量也可能是不安全的,除非將它們聲明為volatile,或者用鎖保護起來。
說起原子性的操作,是指讀和寫是原子性的,比如i=5;這個就是一個原子性的操作。
但是兩個原子性的操作合在一起進行,就不一定是原子性的了,比如先讀后寫,那么就有可能在讀之后這個變量被修改過。
i++就是這樣的一個操作,先讀后寫,所以說整型變量是原子性的,不是說i++就是一個原子性的操作。
當你使用for(int i=0; i<10000; i++){System.out.print(i)}
你會發現,i到最后不會打印出10000,打印出8-9千左右。
但是在多線程的情況下,就算整型變量是原子性的,也有可能會出現線程安全的問題,這個是線程可見性的問題,所以需要加上volatile聲明才行,
該修飾符是強制變量每次從內存中讀取,而不會存儲在寄存器中。