Java基礎筆記(四:多線程基礎及生命周期)

来源:http://www.cnblogs.com/liuzhen1995/archive/2016/09/14/5872836.html
-Advertisement-
Play Games

一、多線程基礎 編寫線程程式主要是構造線程類。構造線程類的方式主要有兩種,一種是通過構造類java.lang.Thread的子類,另一種是通過構造方法實現介面java.lang.Runnable的類。因為類java.lang.Thread實際上也是實現了介面java.lang.Runnable的類, ...


一、多線程基礎

    編寫線程程式主要是構造線程類。構造線程類的方式主要有兩種,一種是通過構造類java.lang.Thread的子類,另一種是通過構造方法實現介面java.lang.Runnable的類。因為類java.lang.Thread實際上也是實現了介面java.lang.Runnable的類,所以上面兩種構造線程類的方法從本質上都是構造實現介面java.lang.Runnable的類。下麵將具體介紹著兩種方法。

(1)通過類Thread的子類構造線程

 java.lang.Thread的每個實例對象就是Java程式的一個線程,但是一般只能通過構造其子類的實例對象來實現。構造類java.lang.Thread的子類的主要目的是為了讓線程類的實例對象能完成線程程式所需要的功能。

  在編寫類java.lang.Thread的子類的過程中,一個很重要的步驟就是編寫run成員方法。這個成員方法實際上是對類java.lang.Thread的成員方法public void run()的覆蓋。它包含了線程所需要執行的代碼。雖然線程的執行代碼在成員方法run中,但是啟動或運行線程並不是直接調用成員方法run的,而是調用類java.lang.Thread的成員方法public void start()啟動線程。

  如果直接調用成員方法run,則一般來說會立即執行成員方法run,從而失去線程的特性。在調用成員方法start之後,Java虛擬機會自動啟動線程,從而由Java虛擬機進一步統一調度線程,實現各個線程一起併發運行。Java虛擬機決定是否開始以及何時開始運行該線程,而線程的運行實際上就是執行線程的成員方法run

(2)通過介面Runnable構造線程

    Java語言的語法規定每個類只能有一個直接父類,所以通過介面java.lang.Runnable構造線程是在構造線程過程中可能出現的多重繼承問題的一種解決方案。

通過介面java.lang.Runnable構造線程首先需要編寫一個實現介面java.lang.Runnable的類。介面java.lang.Runnable只聲明瞭唯一的成員方法void run(),因此,編寫實現介面java.lang.Runnable的類的一般格式如下:

public class A extends B implements Runnable

{

    //類體的其它部分

    public void run()

    {

       成員方法run的方法體

    }

    //類體的其它部分

}

  其中,AB分別表示兩個類的名稱。在上面的格式中,“extends B”不是必須的,是否需要應當由具體需求而定。如果“extends B”是必須的,則通過介面java.lang.RUnnable構造線程的方法似乎是非常有必要的。因為類A已經有一個直接父類B,所以類A不能再是類java.lang.Thread的直接子類。藉助於介面java.lang.Runnable可以避開這個問題。與通過構造類java.lang.Thread的子類創建線程的方法類似,由類A構造出來的線程的執行代碼就封裝在類A的成員方法run中。這裡編寫的run成員方法實現了對介面java.lang.Runnable的成員方法run的覆蓋。

  在編寫玩實現介面java.lang.Runnable的類A之後,構造和啟動線程的方法如下:

A  a = new A();

Thread  t = new Thread(a);

T.start();

(3)後臺線程

  線程可以分為後臺線程和用戶線程。後臺線程在有些資料中也稱為守護線程或精靈線程。它和用戶線程的區別隻是在於當在一個程式中只有後臺線程在運行時,程式會立即退出。如果一個程式還存在正在運行的用戶線程,則該程式不會中止。因此,後臺線程通常用來為其他線程提供服務。在預設情況下,線程是用戶線程。

  一般通過類java.lang.Thread的成員方法public final boolean isDaemon()來判斷一個線程是用戶還是後臺線程。通過類java,lang.Thread的成員方法public final void setDaemo(boolean on)可以將線程狀態在用戶線程和後臺線程之間切換,在調用該方法時,一定要在public void start()方法被調用之前調用,否則將會報錯。

(4)線程組

  線程可以通過線程組(類java.lang.ThreadGroup的實例對象)來進行管理。這裡的線程組是一些線程和線程組的集合。因為線程組可以包含其他線程組,所以線程組實際上形成了一個樹狀的體繫結構。除了樹狀結構根部的線程組之外,每個線程組都有一個父線程組。一個線程組的父線程組就是包含該線程組的線程組。

  構造線程組可以通過類java.lang.ThreadGroup的兩個構造方法。其中,一個構造方法是:

    public ThreadGroup(String name),它的參數name用來用來指定線程組的名稱,這時構造出來的線程組的父線程組就是當前線程所在的線程組。

  另一個構造方法是:

    public ThreadGroup(ThreadGroup parent,String name),其中參數parent指定父線程組,參數name指定新構造的線程組的名稱。

  將一個線程添加到一個線程組中一般是在創建線程時通過線程的構造方法的參數指定線程組。例如,類java.lang.Thread的構造方法:

     public Thread(ThreadGroup group,String name)的參數group指定所要添加到的線程組,參數name指定新創建的線程的名稱。

 

 

二、線程的生命周期

  線程的生命周期基本上如下圖所示:

 

 

  在正常的程式流程中,線程一般要經歷新生態、就緒態、運行態和死亡態這4個基本狀態。有時由於線程的併發等原因,還可能進入阻塞態。另外,根據程式的需要,線程還有可能進入等待態和睡眠態。

  剛剛創建的線程還不能與其他線程一同併發運行。這時需要調用線程的成員方法start,使得線程進入就緒態。只有處於就緒態的線程才能參與Java虛擬機對線程的調度。Java虛擬機按照一定的調度規則讓一些處於就緒態的線程進入運行態。進入運行態的線程自動執行線上程的成員方法public void run()中的代碼。在執行run成員方法代碼之後,線程自動進入死亡態。

    Java虛擬機對線程的調度首先要根據線程的優先順序。每個線程都有優先順序。Java虛擬機規定所有線程最小的優先順序大小為1,最大為10

  線上程調度的過程中,如果存在多個處於就緒態的線程,則優先順序高的線程優先進入運行態。如果存在資源共用衝突,則優先順序高的線程優先占用該資源。如果線程的優先順序都一樣,則Java虛擬機隨機調度這些線程進入運行運行態或占用資源。如果多個線程共用資源,並且只能有限個線程同時占用該資源,則Java虛擬機在調度就緒態的線程時會讓一些處於就緒態的線程占用這些資源,而其他處於就緒態的線程就會因為資源短缺而自動進入阻塞態。處於阻塞態的線程在所需要的資源準備就緒(例如其他線程退出這些資源)時會自動重新進入就緒態,再次由Java虛擬機進行調度。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近在看《演算法導論》這本書,在練習題當中發現了這樣的一個問題:使用二分查找法來實現插入排序,由於之前的內容當中有講解二分法的遞歸實現,所以在這便將它們結合起來希望解決這個問題。閑話不多說了,直接上代碼: 演算法思路很簡單,無非是將原來的線性查找被排序元素的合適的位置的部分換成了使用二分法來查找合適的位 ...
  • 建議47:在equals中使用getClass進行類型判斷 本節我們繼續討論覆寫equals的問題,這次我們編寫一個員工Employee類繼承Person類,這很正常,員工也是人嘛,而且在JavaBean中繼承也很多見,代碼如下: 員工類增加了工號ID屬性,同時也覆寫了equals方法,只有在姓名和 ...
  • http://stackoverflow.com/questions/5669878/when-to-close-cursors-using-mysqldb I'm building a WSGI web app and I have a MySQL database. I'm using MySQ ...
  • 我的車就差一個輪子啦,造好輪子,我就飛上天與太陽肩並肩啦,想想都激動。什麼你要自己造輪子,是不是傻,商店裡不都是別人造好的嗎,又好又方便,只需一點money,你沒有money,那你只能做個安靜的美男子啦。幸運的是編程世界中的輪子不需要money,今天就來看看如何調用庫中的輪子。 今天的內容: 一.修 ...
  • 一、關於匈牙利演算法 匈牙利演算法是由匈牙利數學家Edmonds提出的,用增廣路徑求二分圖最大匹配的演算法。 聽起來高端,其實說白了就是: 假設不存在單相思(單身狗偷偷抹眼淚),在一個同性戀不合法的國家裡(不存在任何歧視#正色),有一些男人和女人,他們互相之間存在一些互相愛戀的關係。而匈牙利演算法就是要促成 ...
  • 文章版權由作者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/ 1.背景 在某個項目中,發現當tree上加上checkbox後,初始化該樹時會特別慢。現場樹上的節點最深有三層,節點個數總和有200多個。經排查,為該tree的參數中開啟了 ...
  • 一、java反射的含義: JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。 二、反射機制的作用: 1,反編譯:.class-->.java; ...
  • 我們知道: int i = 5; long j = 7; i = i + j不能編譯,但i += j卻能編譯運行,結果i = 12。 這是因為: i += j 等同於 i = (int)(i+j); 總結就是:對複合賦值表達式來說,E1 op= E2 (諸如 i += j; i -= j 等等),其 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...