第14章 多執行緒程式設計
第14章 多執行緒程式設計
執行緒的基本概念 並行:CPU同一時刻執行多個任務 併發:CPU不同的程式碼交替的實現 程序是唯一的分配單位 執行在程序裡面的多個任務就叫執行緒 一個正在執行的程式通常稱為一個程序(Process),每個程序都有自己獨立的一塊記憶體空間,每個程序的內部資料和狀態都是完全獨立的。
執行緒建立 編寫一個繼承Thread類的類,然後在類中重寫Thread類的run()方法 編寫一個類實現Runnable介面,然後將該類的例項與java.lang.Thread物件聯絡在一起 通過繼承Thread類來建立執行緒 1、建立一個繼承Thread類的類 2、在建立的Thread子類中重寫run()方法,在方法中寫入想要執行緒執行的程式碼 3、建立Thread子類的例項 4、通過呼叫該例項上的start()方法,開始執行執行緒 通過實現Runnable介面來建立執行緒
執行緒的生命週期
新建狀態: 使用 new 關鍵字和 Thread 類或其子類建立一個執行緒物件後,該執行緒物件就處於新建狀態。它保持這個狀態直到程式 start() 這個執行緒。 就緒狀態:
守護執行緒 守護(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()方法時,會喚醒使用相同物件的所有執行緒,並讓優先權最高的執行緒準備執行
該機制的主要目的是在保證共享資料的一致性,並預防程式進入死鎖的狀態