多執行緒的安全問題

2021-05-23 06:20:31 字數 1805 閱讀 9948

首先先提出幾個問題:

1.多執行緒程式設計何時會出現執行緒不安全的問題?

2.如何解決執行緒不安全的問題?

執行緒不安全的本質是多執行緒共享資料,那麼什麼情況下多執行緒會共享資料?無外乎這麼幾種情況:

(1)多執行緒訪問單例項中的例項變數

(2)多執行緒訪問靜態變數

下面將舉例說明,這個例子模擬鐵路售票系統,實現通過四個售票點發售某日某次列車的100張車票,詳見貼所示:http://bbs.misonsoft.com/thread-1225-1-1.html(建立執行緒兩種方式的比較)。

第一種情況:多執行緒訪問單例項中的例項變數

列印結果:

thread-2 is saling ticket 100

thread-1 is saling ticket 99

thread-3 is saling ticket 98

。。。thread-2 is saling ticket 2

thread-0 is saling ticket 1

thread-3 is saling ticket 0

thread-1 is saling ticket -1

thread-2 is saling ticket -2

複製**

這個**展示了多執行緒訪問單例項中的例項變數而導致的資料不同步問題。多執行緒就是4個售票視窗,即new thread(t),單個例項便是threadtest類,共享的資料就是該例項的tickets變數,即為100張車票。而出現的資料不同步現象有兩種情況:乙個是賣出超過100張車票(如列印結果所示售出102張),還有一種情況是同個座位的車票賣出了多次(本例不會出現)。

接下來說明一下造成資料不安全的第二種情況:多執行緒訪問靜態變數

上述**就是多執行緒訪問靜態變數導致的資料不同步問題,因為4個執行緒共享ticket這個靜態資料,所以也會導致賣出超過100張車票。

我們再來舉個多執行緒共享靜態資料的例子,懶漢式的單例模式並非執行緒安全的,如下:

執行結果:

物件建立了1次

singleton@10b30a7

物件建立了2次

singleton@1a758cb

物件建立了3次

singleton@1b67f74

物件建立了4次

singleton@69b332

物件建立了5次

singleton@173a10f

很明顯,該物件建立了5次,每乙個執行緒都建立了乙個物件。

總結一下,當多執行緒共享資料時,該資料極有可能出現不同步的狀況。接下來就是第二個問題了:如何防止執行緒不安全的狀況發生。加鎖可以解決這個問題,每個物件和每個類都提供了一把鎖,當多執行緒中某乙個執行緒持有這把鎖的時候,所有其他執行緒都必須等待該執行緒執行完畢釋放鎖之後才能繼續執行。這把鎖是哪個物件提供的或者是哪個類提供的並不重要,關鍵是該鎖必須是唯一的,因為只有唯一的物件鎖才是排他的。

因此第乙個場景的**可以做如下修改:

也可以這樣加鎖:

甚至可以這樣加鎖:

因此只要確保該鎖是唯一的,即可達到同步的效果。

再來看下第二個場景的資料不同步問題如何解決:

這樣加鎖能否解決問題:

很顯然,這樣加鎖並不能達到同步的目的,因為當前物件並不是唯一的,這裡的當前物件就是每次建立的執行緒物件,這裡有4個執行緒物件,每個物件指代的當前物件都是不一樣的,因此加的鎖都是不一樣的鎖,無法達到排他的目的,因此仍然會造成賣出超過100張車票。這個**可以定義乙個static物件做為鎖,或者以threadtest.class作為鎖。

最後單例模式如何加鎖留給大家思考。

總結:加鎖是解決執行緒不安全的方法之一,加鎖的時候必須確保該鎖是唯一的。

多執行緒安全問題

這裡的安全問題可以理解為 實現在邏輯上的問題,比如 火車站賣票 100張票讓4個人去賣,一定不能出現賣的票是負數問題,那麼開啟多執行緒後,如何才能保證賣的票不可能存在負數呢?常用的解決方法有兩種 1,使用同步 塊,把需要同步的 再放同步 塊中 2,使用同步函式 同步的鎖,可以理解為就是那個物件!同步...

多執行緒(多執行緒的安全問題)

多執行緒的執行出現安全問題。非常可怕的問題,一出問題比較惱火 問題原因 重點 當多條語句在操作同乙個執行緒共享資料時,乙個執行緒對多條語句只執行了一部分,還沒執行完,另乙個執行緒參與進來執行。導致共享資料的錯誤。解決方法 對多條操作共享資料的語句,只能讓乙個執行緒都執行完,在執行過程中,其他執行緒不...

多執行緒的安全問題

需要同步操作共享資料的 塊 一 產生的原因 1 執行緒任務中有共享資料 2 執行緒任務中有多條對共享資料的操作。乙個執行緒在操作共享資料的過程中,其他執行緒參與了運算,造成了資料的錯誤。二 解決思想 只要保證多條操作共享資料的 在某一時間段,被一條執行緒執行,在執行期間不允許其他執行緒參與計算。三 ...