java i线程安全吗_Java中 i++ 是线程安全的么?为什么?
問(wèn)題
在 int i = 0; i = i++; 語(yǔ)句中,i = i++是線(xiàn)程安全的么?如果不安全,請(qǐng)說(shuō)明上面操作在JVM中的執(zhí)行過(guò)程,為什么不安全?說(shuō)出JDK中哪個(gè)類(lèi)能達(dá)到以上的效果,并且是線(xiàn)程安全而且高效的,簡(jiǎn)述其原理。
回答
語(yǔ)句 i = i++;不是線(xiàn)程安全的。
該語(yǔ)句執(zhí)行過(guò)程如下,
先把 i 的值取出來(lái)放到棧頂,可以理解為引入了一個(gè)第三方變量 k,此時(shí),k的值為i,
然后執(zhí)行自增操作,i的值變?yōu)?,
最后執(zhí)行賦值操作 i = k (自增前的值)
因此執(zhí)行結(jié)束后,i的值還是0.
從上面的分析可知,i = i++語(yǔ)句的執(zhí)行過(guò)程有多個(gè)操作組成,不是原子操作,因此不是線(xiàn)程安全的。
在Java語(yǔ)言中,++i和i++操作并不是線(xiàn)程安全的,在使用的時(shí)候,不可避免的會(huì)用到synchronized關(guān)鍵字。而java.util.concurrent.AtomicInteger是一個(gè)提供原子操作的Integer類(lèi),其提供了線(xiàn)程安全且高效的原子操作,是線(xiàn)程安全的。
AtomicInteger類(lèi)的底層實(shí)現(xiàn)原理是利用處理器的CAS操作(Compare And Swap,比較與交換,一種有名的無(wú)鎖算法)來(lái)檢測(cè)棧中的值是否被其他線(xiàn)程改變,如果被改變則CAS操作失敗。這種實(shí)現(xiàn)方法在CPU指令級(jí)別實(shí)現(xiàn)了原子操作,因此,其比使用synchronized來(lái)實(shí)現(xiàn)同步效率更高。
CAS操作過(guò)程都包含三個(gè)運(yùn)算符:內(nèi)存地址V、期望值E、新值N。當(dāng)操作的時(shí)候,如果地址V上存放的值等于期望值E,則將地址V上的值賦為新值N,否則,不做任何操作,但是要返回原值是多少。這就保證比較和設(shè)置這兩個(gè)動(dòng)作是原子操作。系統(tǒng)主要利用JNI(Java Native Interface,Java本地接口)來(lái)保證這個(gè)原子操作,它利用CPU硬件支持來(lái)完成,使用硬件提供swap和test_and_set指令,但CPU下同一指令的多個(gè)指令周期不可中斷,SMP(Symmetric Multi-Processing)中通過(guò)鎖總線(xiàn)支持這兩個(gè)指令的原子性。
總結(jié)
以上是生活随笔為你收集整理的java i线程安全吗_Java中 i++ 是线程安全的么?为什么?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Leetcode-单调数列(896)
- 下一篇: ElasticSearch wildc