1. 程式人生 > >java多執行緒的一些小技巧,小白必備!

java多執行緒的一些小技巧,小白必備!

什麼是多執行緒呢?多執行緒是為了使得多個執行緒並行的工作以完成多項任務,以提高系統的效率。執行緒是在同一時間需要完成多項任務的時候被實現的。

在Java中如何實現執行緒

在Java語言層面上只有兩種實現執行緒的方式。繼承java.lang.Thread類和實現java.lang.Runnable介面。java.lang.Thread代表了一個執行緒,而java.lang.Runnable代表了執行緒中執行的任務。

我們應該是使用Runnable還是Thread?

Java不支援多繼承,但允許實現多個介面。所以如果需要繼承其他類,實現Runnable介面是好了。

題外話,Thread表示一個執行緒,每個任務都建立一個執行緒肯定是不妥的,正確的做法應該是初始化一定量的Thread物件,實現Runnable介面建立表示任務的類,並把這些任務對給Thread執行緒執行。

Thread類的start()和run()方法的區別

start()方法會建立新的執行緒並啟動該執行緒,所以該方法會呼叫其他native方法,而run()方法就是正常的Java方法呼叫,即在原來的執行緒中執行java程式碼。

Java停止執行緒的方法

首先必須要明確Java本身沒有提供停止執行緒的方法。特別值得一提的是JDK1.0中的一些控制方法,比如stop(), suspend() 和 resume()等,由於存在潛在的死鎖問題因此在後續的版本中被棄用了。當run() 或call() 方法執行完執行緒就會自動結束,如果確實需要手動結束某個執行緒,可以使用一些變數來標誌是否退出run()或call(),如果沒有采用同步機制,則需要使用volatile修飾,還可以通過取消任務來中斷執行緒,即通過判斷是否中斷。

多執行緒的特性

有序性:程式執行的順序按照程式碼的先後順序執行。

可見性:當多個執行緒訪問同一個變數時,一個執行緒修改了這個變數的值,其他執行緒能夠立即看得到修改的值。

若兩個執行緒在不同的cpu,那麼執行緒1改變了i的值還沒重新整理到主存,執行緒2又使用了i,那麼這個i值肯定還是之前的,執行緒1對變數的修改執行緒沒看到這就是可見性問題。

原子性:即一個操作或者多個操作要麼全部執行並且執行的過程不會被任何因素打斷,要麼就都不執行。

在程式編譯到執行的過程中,程式會經過多次重排序,原始碼->編譯器優化重排序->指令級並行重排序->記憶體系統重排序->最終執行的指令序列,

也就是說我們編寫的程式碼,經過這一連串的重排序後,程式碼很可能就和我們寫的順序不一致了,但是我們的作業系統等會保證我們

最終執行的指令序列與我們的原始碼的結果保持一致,我們的作業系統是可以保證單執行緒的有序性的。

多執行緒帶來的問題

我們模擬這樣一個場景:

有十個使用者同時購票,但是系統中只剩下了8張票,當每個使用者同時開啟自己的執行緒,將主記憶體中8張票複製到工作記憶體中,在方法中,會判斷票數是否滿足要求,此時,十個執行緒都判斷滿足,都要對票數進行操作。

當用戶一操作後,票數=8-1=7,將資料回寫至主記憶體。使用者二操作後,使用者二的本地記憶體中票數為8,則修改後票數=8-1=7,繼續回寫至主記憶體,以此下去,在我們假設十個使用者同時開啟執行緒的情況下最後主記憶體中的票數肯定是7,而且十個使用者均出票成功,出現了超賣的情況,這在現實場景是很危險的事!

好了,本篇文章就分享到這裡了。有興趣的新手夥伴們可以關注收藏起來,以後需要的時候可以多看看。如果有正在學java的程式設計師,可來我們的java技術學習扣qun哦:59789,1510裡面免費送java的視訊系統教程!