1. 程式人生 > >Java 線程控制

Java 線程控制

一段時間 阻塞 狀態 sync 守護線程 並發控制 管理 () 優先級

一、線程控制

  和線程相關的操作都定義在Thread類中,但在運行時可以獲得線程執行環境的信息。比如查看可用的處理器數目(這也行?):

Runtime.getRuntime().availableProcessors();

  線程還提供了一些方法用於對線程進行便捷的控制。22222

  1、線程睡眠

  靜態方法Thread.sleep(long millis)強制正在執行的線程暫停進入睡眠狀態,進入阻塞狀態。睡眠結束後,線程轉為就緒狀態。

/*自定義的睡眠時間單位為毫秒*/
/*必須要進行異常處理*/
try {
    Thread.sleep(lengthOfPause);
} catch
(InterruptedException e) { e.printStacktrace(); }

  值得強調的是:

  • 線程睡眠是幫助其他所有線程獲得運行機會的最好方法;
  • 線程睡眠到期自動蘇醒,並返回到就緒狀態,不是運行狀態。然後,sleep()中參數指定的時間是停止運行的最短時間,而無法保證從睡眠蘇醒後就開始執行;
  • sleep()是靜態方法,只能控制當前正在運行的線程;

  2、線程讓步

  yield()方法使當前線程讓出CPU占有權,與sleep()類似,但讓出時間無法設定。而且yield()使線程進入就緒狀態,更利於有同優先級的其它線程獲得運行機會。只是實際中,無法保證yield()達到讓步目的,比如讓步的線程又被JVM選中。

  yield()方法不會釋放鎖標誌。實際上,yield()方法對應了如下操作:先檢測當前是否有相同優先級的線程處於就緒狀態。若有,則把CPU占有權交給此線程;若沒有,繼續運行原來的線程。所以yield()嘗試做的,是把運行機會給同等級的其它線程,而無法讓低級別的線程獲得。

  3、線程加入

  在當前線程中調用另一個線程的join()方法,則當前線程轉入阻塞狀態。直到另一個線程運行結束,阻塞的線程重回就緒狀態。

  join()是Thread類的非靜態方法,還有帶有超時限制的重載版本,如t.join(5000)是讓線程等待5000ms,超時後,阻塞的進程進入就緒狀態。

  4、線程優先級

  當應用啟動時,主線程是創建的第一個用戶線程,程序可以創建多個用戶線程和守護線程。

  當所有的用戶線程執行完畢,JVM終止進程。

  設置線程的優先級:

/*優先級為1~10*/
Thread t=new MyThread();
/*設置線程優先級*/
t.setPriority(8);
/*獲取線程優先級*/
t.getPriority();
t.start();

//只是說優先級更高的線程有更多的機會獲得運行,並不保證先於優先級低的線程運行。

  守護線程的優先級別是最低的,用於為系統中的其他對象和線程提供服務,例如JVM中的資源自動回收線程。

  將一個用戶線程設置為守護線程的方法是在線程對象創建之前調用線程對線的setDaemon()方法。

  5、線程分組管理

  ThreadGroup類

  一旦線程加入某個線程組,該線程就一直存在於該線程組中直至死亡,不能中途改變線程所屬的組。

  二、線程同步

  線程調度的意義在於,JVM對運行的多個線程進行系統級別的協調,以避免多個線程爭奪有限的資源而導致應用崩潰。

  同步是一種防止對共享資源訪問導致數據不一致的機制。即當多個線程訪問同一個共享資源時,需要確保該資源在一段時間內僅被一個線程訪問。

  1、鎖機制

  關鍵字synchronized為代碼塊or方法加鎖,實現同步。線程在使用臨界資源時加鎖,拒絕其他線程的訪問,直至該線程解鎖。

  實際上,任何對象都有一個監視器用於加鎖和解鎖,當synchronized聲明的代碼塊or方法被執行時,說明當前線程已經成功獲取了對象監視器上的鎖。當正常執行完畢或異常退出時,當前線程所獲取的鎖會被自動釋放

  線程可以在一個對象上加多次鎖,JVM保證獲取鎖之前和釋放鎖之後的變量的值是與主存中的內容同步的。

  1、同步方法

  使用synchronized聲明方法。

  當訪問某個對象的同步方法,這個對象會加鎖!因此當對象的同步方法被某個線程執行時,其他線程無法訪問該對象的任何同步方法,但是可以調用其它非同步方法。

  當調用一個對象的靜態同步方法時,它鎖定的是同步方法所在對象對應的Class對象。因此,其他線程不能調用該類的其他靜態同步方法,但是可以調用非靜態同步方法。

  2、同步代碼塊

  使用synchronized聲明同步代碼塊,鎖定其所在的對象or特定的對象,還對象作為可執行的標誌從而達到同步效果。

  3、同步方法是一種粗粒度的並發控制,某一時刻只能有一個線程執行該同步方法。同步代碼塊是細粒度的並發控制,只會將塊中的代碼同步,代碼塊之外的代碼可被其他線程同時訪問。

  使用synchronized要註意:

  • synchronized關鍵字不能繼承;
  • 定義接口方法時不能使用synchronized;
  • 構造方法不能使用synchronized關鍵字,但可以使用synchronized代碼塊進行同步;

  三、線程協作

  線程之間會有協作關系,一起來完成某項任務。如生產者—消費者模式。

  多線程可以通過訪問和修改同一份資源(對象)來進行交互和通信,只是需要註意線程訪問的安全性。當線程所要求的資源不足時,就進入等待狀態;而另外的線程則負責在合適的時機發出通知來喚醒等待中的線程。

  等待—通知機制是完成線程間同步的基本機制。

  1、wait與notify原語

  2、生產者-消費者問題

  四、線程池

  五、線程同步控制的新特征

Java 線程控制