高级java必须清楚的概念:原子性、可见性、有序性
轉(zhuǎn)載自?高級(jí)java必須清楚的概念:原子性、可見性、有序性
原子性、可見性、有序性是多線程編程中最重要的幾個(gè)知識(shí)點(diǎn),由于多線程情況復(fù)雜,如何讓每個(gè)線程能看到正確的結(jié)果,這是非常重要的。
原子性
原子性是指一個(gè)線程的操作是不能被其他線程打斷,同一時(shí)間只有一個(gè)線程對(duì)一個(gè)變量進(jìn)行操作。在多線程情況下,每個(gè)線程的執(zhí)行結(jié)果不受其他線程的干擾,比如說多個(gè)線程同時(shí)對(duì)同一個(gè)共享成員變量n++100次,如果n初始值為0,n最后的值應(yīng)該是100,所以說它們是互不干擾的,這就是傳說的中的原子性。但n++并不是原子性的操作,要使用AtomicInteger保證原子性。
可見性
可見性是指某個(gè)線程修改了某一個(gè)共享變量的值,而其他線程是否可以看見該共享變量修改后的值。在單線程中肯定不會(huì)有這種問題,單線程讀到的肯定都是最新的值,而在多線程編程中就不一定了。
每個(gè)線程都有自己的工作內(nèi)存,線程先把共享變量的值從主內(nèi)存讀到工作內(nèi)存,形成一個(gè)副本,當(dāng)計(jì)算完后再把副本的值刷回主內(nèi)存,從讀取到最后刷回主內(nèi)存這是一個(gè)過程,當(dāng)還沒刷回主內(nèi)存的時(shí)候這時(shí)候?qū)ζ渌€程是不可見的,所以其他線程從主內(nèi)存讀到的值是修改之前的舊值。
像CPU的緩存優(yōu)化、硬件優(yōu)化、指令重排及對(duì)JVM編譯器的優(yōu)化,都會(huì)出現(xiàn)可見性的問題。
有序性
我們都知道程序是按代碼順序執(zhí)行的,對(duì)于單線程來說確實(shí)是如此,但在多線程情況下就不是如此了。為了優(yōu)化程序執(zhí)行和提高CPU的處理性能,JVM和操作系統(tǒng)都會(huì)對(duì)指令進(jìn)行重排,也就說前面的代碼并不一定都會(huì)在后面的代碼前面執(zhí)行,即后面的代碼可能會(huì)插到前面的代碼之前執(zhí)行,只要不影響當(dāng)前線程的執(zhí)行結(jié)果。所以,指令重排只會(huì)保證當(dāng)前線程執(zhí)行結(jié)果一致,但指令重排后勢(shì)必會(huì)影響多線程的執(zhí)行結(jié)果。
雖然重排序優(yōu)化了性能,但也是會(huì)遵守一些規(guī)則的,并不能隨便亂排序,只是重排序會(huì)影響多線程執(zhí)行的結(jié)果。
總結(jié)
以上是生活随笔為你收集整理的高级java必须清楚的概念:原子性、可见性、有序性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java多线程中的死锁、活锁、饥饿、无锁
- 下一篇: 如何quot;优雅quot;地终止一个线