多線程(二)

接着來討論java中多線程問題。


先說一個問題:  現在有兩個線程,怎麼樣才能讓一個線程執行結束之後再執行另一個線程。

其實只要講要先執行的線程設置爲加入線程就行了。-->join()


這裏寫一下怎麼來實現

假如現在有兩個線程m1和m2,現在要讓m1先執行,也就是講m1設置爲加入線程。要抓一個異常。

try {
mt1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

關於線程死亡:

   public final void stop():直接殺死

   public void interrupt():直接殺死,在死前,還可以有遺言

來說一下倆者的區別:

stop是直接將線程殺死

interrupt:線程再被殺死後,會把後邊的代碼執行完,然後再死亡,就是我們說的留遺言。


線程的生命週期(畫圖講解),面試題

1.新建

2.就緒

3.運行

4.有可能阻塞

5.死亡



wKioL1klgu-j_xv0AADNboBF3zo831.jpg-wh_50

生命週期圖解如上圖


這裏來一個案例   

案例:以給學生設置和獲取姓名和年齡爲例,演示線程通信問題

  線程間通訊:

  資源:Student

  設置數據線程:SetThread

  獲取數據線程:GetThread

  測試類:StudentDemo

  

  問題1:控制檯出現的結果是:null---0

  設置和獲取線程使用的學生資源不是同一個。

  如何解決這個問題呢?

  把資源作爲構造參數傳遞即可。

  

  問題2:產生了2個問題

  相同的數據出現了多次

  CPU的一點點時間片就足夠我們的程序執行很多次

  數據出現了問題(數據安全問題)

  是否是多線程環境

 

  是否有共享數據

 

  是否有多條語句操作共享數據

 

  既然我們知道它是出現了數據安全問題,我們就應該來解決它。

  如何解決呢?加鎖

  

  問題3:加了鎖以後,數據還是有問題

  多個線程都要加鎖

  多個線程加的鎖必須是同一把鎖


以上問題是這個程序中輝徐導的問題,也是必須要解決的。通過這個案例,我們對多線程應該會有一個更爲系統,更爲全面的認識。


大家可以自己去實現,代碼詳見第十六天資料  com.edu_04


關於線程池

程序啓動一個新線程成本是比較高的,因爲它涉及到要與操作系統進行交互。而使用線程池可以很好的提高性能,尤其是當程序中要創建大量生存期很短的線程時,更應該考慮使用線程池。

線程池的特點:

線程池裏的每一個線程代碼結束後,並不會死亡,而是再次回到線程池中成爲空閒狀態,等待下一個對象來使用。

在JDK5之前,我們必須手動實現自己的線程池,從JDK5開始,Java內置支持線程池


線程池的創建機操作

//提交給線程池兩個任務,
ExecutorService pool = Executors.newFixedThreadPool(2);
//創建任務
MyRunnbale my1 = new MyRunnbale();
MyRunnbale my2 = new MyRunnbale();
//3.提交任務
pool.submit(my1);
pool.submit(my2);
//關閉線程池
//void shutdown()
pool.shutdown();

另外在run方法中寫入要運行的代碼就好了。  這裏線程池的創建的方法要記住,他不同於new對象,是調一個工廠類方法。


java中多線程方面就已經結束了,來簡單總結一下,並說說該注意的。


線程的實現有兩種方法,繼承Thread類或者實現runnable接口。一般推薦使用實現runnable接口這一種方法,因爲他更能體現面向對象的思想,還有一個重要的原因,大家都知道,在java中,支持單繼承多實現,如果用第二種方法,還可以繼承別的類,實現更多的接口。


多線程中會有線程不安全的問題,在編寫代碼的時候要注意解決。


要了解線程的生命週期,理解調用start之後,僅僅只是就緒狀態,只有在搶到cpu放入時間片的時候,才執行。


線程池裏的線程在執行完代碼之後並不會死亡,會自己回到線程池中等待下一個線程對象調用,所以,創建一個含有兩個線程的線程池,並不是只能以操作兩個線程,只要等到一個線程執行完畢,就可以在使用線程池裏的線程。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章