竟然將線程安全講的如此清新脫俗,談談你對線程安全性的理解!
1.官方定義
線程安全通常是相對于多線程或者并發(fā)的情況下而言的。如果是單線程操作的話,就無所謂線程安全了。
簡單來說,就是在多個線程環(huán)境下,訪問同一個對象時,如果不用考慮這些線程在運行時環(huán)境下的調度和交替執(zhí)行,在不做任何干預的強可選,調用這個對象的行為都可以獲得預期的結果,那么這個對象就是線程安全的。
看完這段,是不是還是很難理解?下面,我來分享一下看我是如何理解的。
2.Tom的理解
我認為,在多線程環(huán)境下保證線程安全,無非就是保證對對象訪問的原子性、有序性和多個線程之間的可見性。
原子性呢,說的是當一個線程執(zhí)行一系列程序指令操作的時候,它應該是不可中斷的,因為一旦出現(xiàn)中斷,站在多線程的視角來看,這一系列的程序指令會出現(xiàn)前后執(zhí)行結果不一致的問題。
這個和數(shù)據(jù)庫里面的原子性是一樣的,簡單來說就是一段程序只能由一個線程完整的執(zhí)行完成,而不能存在多個線程干擾。CPU的上下文切換 , 是導致出現(xiàn)多線程原子性問題的核心原因 , 而JDK面也提供了synchronized 關鍵字來解決原子性問題。
然后,就是可見性,相當于在多線程環(huán)境下,可能會存在讀和寫是發(fā)生在不同的線程里面,有可能出現(xiàn)某個線程對共享變量的修改,對其他線程不是實時可見的。導致可見性問題的原因有很多,比如 CPU的高速緩存、CPU的指令重排、編譯器的指令重排等因素。
最后,就是有序性,指的是程序編寫的指令順序和最終 CPU 運行的指令順序可能出現(xiàn)不一致的現(xiàn)象,這種現(xiàn)象也可以稱為指令重排序,所以有序性也會導致可見性問題。可見性和有序性可以通過JDK提供的volatile 關鍵字來解決。
我認為,導致有序性、原子性、可見性問題的本質,是計算機設計的時候,為了最大化提升 CPU 利用率導致的。比如CPU設計了三級緩存、設計了 StoreBuffer、設計了緩存行這種預讀機制、在操作系統(tǒng)里面,設計了線程模型、在編譯器里面,設計了編譯器的深度優(yōu)化機制等等。
我們都在說,面試造火箭,工作擰螺絲。對于企業(yè)來說,如果選擇一個對計算機底層原理了解更透徹的程序員,不用擔心他濫用線程導致一些不可預測的安全問題。其實也是在降低用人成本。
最后,我把之前分享的視頻全部整理成了文字,想獲取的小伙伴可以從我的個人煮葉簡介中找到,希望能夠以此來提高各位粉絲的通過率。
我是被編程耽誤的文藝Tom,如果我的分享對你有幫助,請動動手指一鍵三連分享給更多的人。關注我,面試不再難!