線程安全,這詞你懂了嗎?
前言
還記得你第一次遇到「線程安全」這個詞的時候嗎?
我第一次遇到線程安全這個詞是在學習多線程並發操作的時候,看到人家文章里出現這個詞,還有說各種線程安全的類,但是一開始並不理解線程安全是什麼意思,也沒去深究線程怎樣是安全的?怎樣是不安全的?只是腦子裡接收了這麼一個詞。
線程安全是多線程編程時的計算機程序代碼中的一個概念。在擁有共享數據的多條線程並行執行的程序中,線程安全的代碼會通過同步機制保證各個線程都可以正常且正確的執行,不會出現數據污染等意外情況。——《百度百科》
默認已學前置知識
- 進程:程序的一次執行的過程,是動態的,是系統進行資源分配的基本單位。一個進程里可以有多個線程。
- 線程:是一個系統進行調度的基本單位,是能獨立運行的。
下面開始回爐重造!打好基礎!
線程安不安全是怎樣定義的?
先給出個問題,為什麼有線程安全這個詞?這個詞是怎麼來的?可能這裡會有點懵,不過沒事,我來回答。
在多線程的情況下,我們會遇到這樣一個問題,這裡舉例 A、B、C 三個線程,它們共同操作同一個資源(吶,這裡同一個資源指的是,變量,方法這些,更準確的話,應該說是內存,畢竟值都是存儲內存中的)。記住,前提是多線程,畢竟如果你單線程,就不可能不安全了,單線程直接安安全全!
這三個線程同時操作,就可能出現這樣的問題,比如舉個具體的例子,經典例子,買票(老演員了)!啥票都行。
三個線程代表三個人,票的剩餘量對於這三個線程來說就是共享資源。
設票的剩餘量為10,記 ticketSurplus = 10
。三人購票,那麼肯定需要對這個剩餘量進行減一操作的。
public void buy() {
ticketSurplus = ticketSurplus - 1;
System.out.println(ticketSurplus);
}
那麼現在同時執行,就很大可能會出現這樣的情況,如圖所示(假設這三個線程執行順序是A、B、C,實際上順序是不確定的):
從上面可以看出,輸出結果為:9,9,8
,而從上帝視角來看,顯然是錯誤的,因為兩個人買了票,不能只減一張票的值,正確的結果應該為9,8,7
。
所以,在多線程並發的情況下,這就是所謂的「不安全」,即不能正確執行,結果出現了混亂(數據污染)。
線程安全?
所謂線程安全,就是指當並發情況下,也就是有多個線程操作同一個資源(具體的話,這裡同一個資源可以看成上面例子中的 ticketSurplus,當然這個同一資源也不一定只的是一個變量,也可以是某一個方法),能不能保證這個資源的一致性,如果任何時候都能夠保證這種正確的操作結果,那麼就可以說是線程安全的。
如何保證線程安全?
在學習操作系統的時候,我們學習了進程管理的內容,其中就有個「進程同步」的概念,所謂進程同步,說簡單點就是進程之間具有前後的執行關係。在並發的情況下,不同進程有不同制約關係,比如某些情況下我們是需要 A 進程先執行,然後 B 進程再執行的,但是操作系統具有「異步性」,在並發的情況下,可能出現 B 先執行,A 後執行了,這顯然不是我們想要的,所以如果不制約,不控制進程的同步,就會出現上面說的情況。
當然,除了「同步」這個詞,還有一個詞——「互斥」,互斥也是用於控制進程之間關係的。
同步:完成某種任務,需要進程之間的執行順序有先後順序,相互協調工作。
互斥:一個進程進入臨界區訪問臨界資源,那麼剩下的進程就需要進行等待,只有當它退出臨界區,才允許下一個進程訪問。
在 Java 中,我們可以通過 synchronized 關鍵字來保證臨界區的同步互斥,當然還有其他的鎖也可以實現同步互斥,進而保證多線程運行的安全。
總的來說,在多線程的情況下,通過加鎖的方式保證線程安全。
最後的最後
由本人水平所限,難免有錯誤以及不足之處, 屏幕前的靚仔靚女們
如有發現,懇請指出!
最後,謝謝你看到這裡,謝謝你認真對待我的努力,希望這篇博客對你有所幫助!
你輕輕地點了個贊,那將在我的心裏世界增添一顆明亮而耀眼的星!