1. 程式人生 > >JAVA-初步認識-第十三章-多線程(線程安全問題的現象)

JAVA-初步認識-第十三章-多線程(線程安全問題的現象)

時間短 也不能 image 應該 很多 自己 現在 編譯 小問題

一. 引言

接著看,把售票的問題給說完,這裏涉及到一個小問題。

技術分享圖片

在我們進行線程任務封裝,並進行線程對象創建的時候,我們發現確實通過四個線程能夠將一百張票賣完。但是賣票的時候,會不會出現一些小問題呢?分析整個程序給大家展示一下。

技術分享圖片

現在有四個線程,都到了run方法中來運行。大家都知道,每個線程所屬的棧區當中都有自己的run方法,比如它們同時在操作堆內存中的變量,叫做num。

技術分享圖片

假設這個num已經減到了1,這是個前提。

技術分享圖片技術分享圖片

在num=1的情況下,四個線程Thread-0,Thread-1,Thread-2,Thread-4,都同時進入循環。在Thread-0線程舉著num=1,判斷完if(num>0)後,cpu切出去執行其他線程的if判斷語句了。也就是說保有執行資格,沒有執行權。在四個線程判別完之後,cpu回過來執行了Thread-0線程,輸出了DOS信息,Thread-0,1,此時num=0了。

同時臥倒的線程還有三個,它們都不用再進行判斷了。線程1在執行的時候,輸出的是Thread-1,0。當線程輸出0的時候,就出事兒了。哪有0號票的,同樣的線程3輸出的是Thread-3,-1。

這個程序分析完,我們發現存在安全隱患。這就是我們在寫多線程程序的時候,必須要註意的一件事。線程的安全問題。

二.

線程的完全問題,多線程是隨機的,它就會引發一些安全隱患。這些安全隱患對我們來說是很嚴重的。

有人說,我們上面的程序在編譯運行的時候,沒有問題。但那都是理想狀態,剛才我們的分析的狀態是有可能出現的。

現在將這種情況實現以下,將線程在臥倒的時候稍微停一下,也就是睡一下。有人說,睡不是釋放資格嗎?不怕,睡的時間特別短就沒事。它具備的資格,沒有執行權和睡的時間短是一回事。因為都在這段時間內,不運行。

線程怎麽睡,自己知道,到Thread類中尋找方法。

技術分享圖片

下面的sleep方法,是納秒。由於sleep方法是靜態的,所以要類名調用。

技術分享圖片

點進sleep方法中,發現還有異常的存在。這個異常是中斷異常,後面會重點給大家介紹。

我們現在調用了一個拋出異常的方法,那應該怎麽辦?要麽聲明throws,要麽try-catch處理。如果catch不了,就聲明出來。

技術分享圖片

在if代碼塊的Thread.sleep(10);語句中,遇到異常了,那麽我們就要選擇拋出,

技術分享圖片

但是在這裏是拋不出去,你聲明不了,是因為這run覆蓋的是接口中的方法,接口沒有聲明過異常,所以覆蓋時,你也不能聲明異常。

你只能try-catch,確切地說,你只能catch,而不能聲明。這就是只能catch,不能聲明的情況。

咱這異常目前處理不了,還沒開始學習怎麽處理這個異常。

技術分享圖片

這裏就沒進行處理,但是真實的catch裏面一定要有處理,而且是針對性的處理。

這麽寫,給大家看一下是否有錯號票發生麽?

技術分享圖片

這次結果中只出了-1,沒有出-2,,只是想說這麽個事兒,自己運行的時候,沒有看到-1,-2,因為到這種情況,當變成0的時候,其他線程才進來,一判斷不滿足就不運行了。

現在的結果將之前談論的安全問題發生了,像這種問題,我們不做下面截圖中那句話,代碼運行很多次都沒有問題,但是只要出現一次就很嚴重。它不是時時刻刻都出現的,但是不代表它沒有安全問題。

技術分享圖片

因此,我們在寫多線程程序的時候,要考慮線程的安全問題。我們要考慮的是造成安全問題的原因是什麽?

JAVA-初步認識-第十三章-多線程(線程安全問題的現象)