1. 程式人生 > >第14章 多執行緒程式設計

第14章 多執行緒程式設計

在這裡插入圖片描述

第14章 多執行緒程式設計

執行緒的基本概念 並行:CPU同一時刻執行多個任務 併發:CPU不同的程式碼交替的實現 程序是唯一的分配單位 執行在程序裡面的多個任務就叫執行緒 一個正在執行的程式通常稱為一個程序(Process),每個程序都有自己獨立的一塊記憶體空間,每個程序的內部資料和狀態都是完全獨立的。

執行緒建立 編寫一個繼承Thread類的類,然後在類中重寫Thread類的run()方法 編寫一個類實現Runnable介面,然後將該類的例項與java.lang.Thread物件聯絡在一起 通過繼承Thread類來建立執行緒 1、建立一個繼承Thread類的類 2、在建立的Thread子類中重寫run()方法,在方法中寫入想要執行緒執行的程式碼 3、建立Thread子類的例項 4、通過呼叫該例項上的start()方法,開始執行執行緒 通過實現Runnable介面來建立執行緒

建立一個類實現Runnable介面,用於代表我們需要執行緒完成的任務 在Runnable指定的run()方法內,放入想要線上程中執行的程式碼 重寫run(),這裡面的程式碼,線上程被CPU選中後,需要執行 建立一個Runnable類的例項 建立一個Thread物件,將Runnable的例項做為構造器引數傳入進去 通過呼叫Thread類的例項的start()方法,開始執行執行緒 通過callable,future介面建立執行緒 該執行緒可以控制主函式運行於子執行緒末

執行緒的生命週期

新建狀態: 使用 new 關鍵字和 Thread 類或其子類建立一個執行緒物件後,該執行緒物件就處於新建狀態。它保持這個狀態直到程式 start() 這個執行緒。 就緒狀態:

當執行緒物件呼叫了start()方法之後,該執行緒就進入就緒狀態。就緒狀態的執行緒處於就緒佇列中,要等待JVM裡執行緒排程器的排程。 執行狀態: 如果就緒狀態的執行緒獲取 CPU 資源,就可以執行 run(),此時執行緒便處於執行狀態。處於執行狀態的執行緒最為複雜,它可以變為阻塞狀態、就緒狀態和死亡狀態。 阻塞狀態: 如果一個執行緒執行了sleep(睡眠)、suspend(掛起)等方法,失去所佔用資源之後,該執行緒就從執行狀態進入阻塞狀態。在睡眠時間已到或獲得裝置資源後可以重新進入就緒狀態。 等待阻塞:執行狀態中的執行緒執行 wait() 方法,使執行緒進入到等待阻塞狀態。 同步阻塞:執行緒在獲取 synchronized 同步鎖失敗(因為同步鎖被其他執行緒佔用)。 其他阻塞
:通過呼叫執行緒的 sleep() 或 join() 發出了 I/O 請求時,執行緒就會進入到阻塞狀態。當sleep() 狀態超時,join() 等待執行緒終止或超時,或者 I/O 處理完畢,執行緒重新轉入就緒狀態。 死亡狀態: 一個執行狀態的執行緒完成任務或者其他終止條件發生時,該執行緒就切換到終止狀態。

守護執行緒 守護(Daemon)執行緒是在後臺執行的執行緒。 setDaemon(true) setDaemon(false)

死鎖 死鎖的發生多半是因為程式設計不佳所造成的,主要原因是來自於物件鎖無法獲得。因此,當我們設計同步程式時,必須仔細考慮每個物件鎖的優先順序。

建立多執行緒程式 執行緒的優先順序 執行緒優先順序分三種,最高為10,最低為1,預設為5 yield()方法 掛起;用yield()方法讓該執行緒讓出執行權,yield()方法會讓執行緒由Running狀態直接回到Runnable狀態,而不會阻塞(Blocked)一段指定的時間 sleep()方法 休眠;可以讓執行緒休眠,休眠過後進入就緒狀態 join()方法 該方法會讓當前正在執行的執行緒暫停執行,並等待呼叫join()方法的執行緒執行完成後,才繼續執行 wait( )方法 讓使用物件的執行緒停止執行,並進入等待,直到另一個使用該物件的執行緒執行notify( )方法

執行緒同步與執行緒之間的相互通訊機制 執行緒同步 當兩個以上的執行緒需要訪問共享資源時,我們必須確定在同一時間點只有一個執行緒能夠存取共享資源,而執行這個目標的過程就稱為同步 同步塊

要設計同步塊程式,我們可以使用Synchronized關鍵字 synchronized 如果用於修飾 物件的話,修飾物件時,除了可以修飾本物件之外,還可以修飾其他物件,//表示的含義是:開啟物件本身的物件鎖,當多根執行緒同時訪問該物件,誰搶的了該物件鎖,誰就可以訪問同步塊的程式碼 synchronized 修飾類物件時候, 此時表示開啟Class物件的物件鎖 //當多根執行緒同時訪問同步塊時,誰搶的了該Class物件的物件鎖,誰就可以訪問同步塊的程式碼 synchronized 也可以用來修飾成員方法,同樣開啟“自身物件”的物件鎖,當多根執行緒同時訪問該方法時,誰搶的了該物件鎖,誰就可以訪問該物件的這個方法 synchronized 還可以修飾類方法,修飾類方法的時候, 此時開啟的Class物件的物件鎖,當多根執行緒同時訪問該方法時,誰搶的了該Class物件的物件鎖,誰就可以訪問該類的這個類方法 如何選擇同步塊, 或者同步方法呢? 1、方法的執行範圍,一定比其中的某一段程式碼執行範圍要大的多(鎖的範圍越大,能夠操作程式碼的人,就越少) 2、同步方法開啟的物件鎖,只能是本物件的,那如果需要開啟其他物件的呢?

同步方法 要設計同步方法程式,我們可以在方法定義時,在方法名前面使用Synchronized關鍵字修飾即可 同步塊比同步方法實用,因為方法比一段程式碼大

執行緒之間的相互通訊

	Java中提供了wait()、notify()和notiyAll()三個方法用於執行緒之間的相互通訊,用於解決上述問題,這種機制稱為“監控器模型(Monitor Model)
	**wait()方法**
		讓使用物件的執行緒停止執行,並進入等待,直到另一個使用該物件的執行緒執行notify()方法
	**notify()方法**
		執行緒在物件中碰到notify()方法時,會喚醒使用相同物件的第一個碰到wait()的執行緒
	**notifyAll()方法**
		執行緒在物件中碰到notifyAll()方法時,會喚醒使用相同物件的所有執行緒,並讓優先權最高的執行緒準備執行
	該機制的主要目的是在保證共享資料的一致性,並預防程式進入死鎖的狀態