1. 程式人生 > >《Java程式設計》第十二章學習總結

《Java程式設計》第十二章學習總結

201711671111《Java程式設計》第十二章學習總結

Java多執行緒機制

1.程序與執行緒

  • 程式是一段靜態程式碼,是應用軟體執行的藍本。
  • 程序是程式的因此動態執行過程,它對應了從程式碼載入、執行至執行完畢的一個完整過程,這個過程也是程序本身從產生、發展至消亡的過程。    
  • 執行緒是比程序更小的執行單位,一個程序在其執行過程中,可以產生多個執行緒,形成多條執行線索,每條線索,即每個執行緒也有它自身的產生、發展至消亡的過程。
  • 沒有執行緒就沒有程序。 

2.java中的執行緒

  • java語言的一大特性點就是內建對多執行緒的支援。多執行緒是指一個應用程式同時存在幾個執行體,按幾條不同的執行線索共同工作的情況,它使得程式設計人員可以很方便地開發出具有多執行緒功能、能同時處理多個任務的功能強大的應用程式。
  • 主執行緒(main執行緒):每個java應用程式都有一個預設的主執行緒。多個執行緒輪流執行。

3.執行緒的狀態與週期

  • java語言使用Thread類及其子類的物件來表示執行緒,新建的執行緒在它的一個完整的生命週期中通常要經歷如下的四種狀態: 
  • ①新建:當一個Thread類或其子類的物件被宣告並建立時,執行緒處於新建狀態。                                                                   
  •  ②執行:JVM將CPU使用權切換給該執行緒時,此執行緒就可以脫離建立它的主執行緒獨立開始自己的生命週期。                         
  •  ③中斷:中斷的原因有四種。
  •  一是JVM將CPU資源從當前執行緒切換給其他執行緒,使本執行緒讓出CPU的使用權處於中斷狀態。
  •   二是執行緒使用CPU資源期間,執行了sleep(int millsecond)方法,使當前執行緒進入休眠狀態。
  •   三是執行緒使用CPU資源期間,執行了wait()方法,使得當前執行緒進入等待狀態。
  • 四是執行緒使用CPU資源期間,執行某個操作進入阻塞狀,比如執行讀/寫操作引起阻塞。                                       
  •  ④死亡:處於死亡狀態的執行緒不具有繼續執行的能力。執行緒死亡的原因有二,一是正常執行的執行緒完成了她的全部工作。    二是執行緒被提前強制性終止。

4.執行緒排程與優先順序

  • JVM中的執行緒排程器管理執行緒,排程器把執行緒的優先順序分為1~10個級別,分別用Thread類的類常量表示。
  • 如果沒有明確地設定執行緒的優先級別,每個執行緒的優先順序為常數5,即Thread.NORM_PRIORITY。
  • 執行緒的優先順序可以通過setPriority(int grade)方法調整,該方法需要一個int型別的引數。
  • Java排程器的任務是使高優先順序的執行緒能始終執行,一旦時間片有空閒,則使具有同等優先順序的執行緒以輪流的方式順序使用時間片。

5.Thread類與執行緒的建立

  • 在java語言中,用Thread類或子類建立執行緒物件。建立執行緒的另一個途徑就是用Thread類直接建立執行緒物件。
  • 在編寫Thread類的子類時,需要重寫父類的run()方法,其目的是規定執行緒的具體操作,否則執行緒就什麼也不做,因為父類的run()方法中沒有任何操作語句。
  • 使用Thread建立執行緒通常使用的構造方法是:Thread(Runnable target)。該構造方法中的引數是一個Runnable型別的介面,因此,在建立執行緒物件時必須向構造方法的引數傳遞一個實現Runnable介面類的例項,該例項物件稱作所創執行緒的目標物件,當執行緒呼叫start()方法後,一旦輪到它來享用CPU資源,目標物件就會自動呼叫介面中的run()方法(介面回撥)。
  • 執行緒間可以共享相同的記憶體單元(包括程式碼與資料),並利用這些共享單元來實現資料交換、實時通訊與必要的同步操作。
  • 從物件和物件之間的關係的角度上看,目標物件和執行緒的關係兩種:                                                                                      ①目標物件和執行緒完全解耦:目標物件不包含對執行緒物件的引用(完全解耦),在這種情況下,目標物件經常需要通過獲得執行緒的名字(因為無法獲得執行緒物件的引用),以便確定是哪個執行緒正在佔用CPU資源,即被JVM正在執行的執行緒。            ②目標物件組合執行緒(弱耦合):目標物件可以組合執行緒,就是將執行緒作為自己的成員。當建立目標物件的類組合執行緒物件時, 目標物件可以通過獲得執行緒物件的引用,來確定是哪個執行緒正在佔用CPU資源,就是被JVM正在執行的執行緒。

6.執行緒的常用方法

  • start():執行緒呼叫該方法將啟動執行緒,使之從新建狀態進入就緒佇列排隊,一旦輪到它來享用CPU資源時,就可以脫離建立它的執行緒獨立開始自己的生命週期了。
  • run():Thread類的run()方法與Runnable介面中的run()方法的功能和作用相同,都用來定義執行緒物件被排程之後所執行的操作,都是系統自動呼叫而使用者程式不得引用的方法。
  • sleep(int millsecond):優先順序高的執行緒可以在它的run()方法中呼叫sleep方法來使自己放棄CPU資源,休眠一段時間。  
  • isAlive():執行緒處於新建狀態時,執行緒呼叫isAlive()方法返回false。線上程的run()方法結束之前,即沒有進入死亡狀態之前,執行緒呼叫isAlive()方法返回true。
  • currentThread():該方法是Thread類中的類方法,可以用類名呼叫,該方法返回當前正在使用CPU資源的執行緒。  
  • interrupt():一個佔有CPU資源的執行緒可以讓休眠的執行緒呼叫interrupt()方法“吵醒”自己,即導致休眠的執行緒發生InterruptedException異常,從而結束休眠,重新排隊等待CPU資源。 

7.執行緒同步

  • 在處理多執行緒問題時,必須注意這樣一個問題:當兩個或多個執行緒同時訪問同一個變數,並且一個執行緒需要修改這個變數。
  • 處理上面這類問題,我們可以用到執行緒同步。
  • 執行緒同步就是若干個執行緒都需要使用一個synchronized修飾的方法。
  • 多個執行緒呼叫  synchronized方法必須遵循同步機制。
  • 執行緒同步機制:當一個執行緒A使用synchronized方法時,其他執行緒想使用的話就必須等待,直到執行緒A使用完該synchronized方法。

8.協調同步的執行緒:

  • 當一個執行緒使用的同步方法用到某個變數,而這個變數又需要其他執行緒修改後才能符合本執行緒的需要,那麼可以再同步方法中用wait()方法。
  • wait():中斷執行緒的執行,使本執行緒等待,暫時讓出CPU的使用權,並允許其它執行緒使用這個同步方法。
  • 其他執行緒如果在使用這個同步方法時不需要等待,那麼它使用完這個同步方法的同時,應當notifyAll()方法通知所有的由於使用這個同步方法而處於等待的執行緒結束等待。曾中斷的執行緒就會從剛才的中斷處繼續執行這個同步方法,並遵循“先中斷先繼續”的原則。
  • notify():只是通知處於等待中的執行緒的某一個結束等待。
  • wait()、notify()、notifyAll()都是object中的final方法,被所有的類繼承但不需要重寫,而且三個方法不可以在非同步方法中使用。

9.執行緒聯合:

  • 一個執行緒A在佔有CPU資源期間,可以讓其它執行緒呼叫join()和本執行緒聯合,如:B.join(); 我們稱A在執行期間聯合了B。
  • 如果執行緒A在佔有CPU資源期間一旦聯合B執行緒,那麼A執行緒將立刻中斷執行,一直等到它聯合的執行緒B執行完畢,A執行緒再重新排隊等待CPU資源,以便恢復執行。如果A準備聯合的B執行緒已經結束,那麼B.join()不會產生任何效果。

9.GUI執行緒

  • 當Java程式包含圖形使用者介面(GUI)時,Java虛擬機器在執行應用程式時會自動啟動更多的執行緒,其中有兩個重要的執行緒:AWT-EventQuecue和AWT-Windows。
  • AWT-EventQuecue執行緒:負責處理GUI事件。
  • AWT-Windows執行緒:負責將窗體或元件繪製到桌面。

 10.計時器執行緒:

  • Java小,swing包中,有一個Timer類。但在使用中應該避免類名混淆。
  • 使用Timer類的方法start()啟動計時器,即啟動執行緒。使用Timer類的方法stop()停止計時器,即掛起執行緒,使用restart()重新啟動計時器,即恢復執行緒 。
  • 計時器的監視器必須是元件類的子類的例項。

11.守護執行緒:

  • 執行緒預設是非守護執行緒
  • 一個執行緒呼叫void setDaemon(boolean on)方法可以將自己設定成一個守護(Daemon)執行緒,例如:thread.setDaemon(true);
  • 當程式中的所有使用者執行緒都已結束執行時,即使守護執行緒的run方法中還有需要執行的語句,守護執行緒也立刻結束執行。