日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

【Java】撩开Java线程的“神秘面纱”

發(fā)布時間:2025/3/15 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java】撩开Java线程的“神秘面纱” 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 一.用一句話講明白進(jìn)程和線程的關(guān)系(不甚嚴(yán)密)
  • 二.淺析進(jìn)程與線程
  • 三.多線程
  • 四.Java中的線程是什么樣子的
  • 五.java.lang.Thread & java.lang.Runnable
    • Thread
    • Runnable
    • 使用run()方法——線程運行體
  • 六.進(jìn)程的生命周期(五狀態(tài)圖)
  • 七.線程的生命周期
    • Java線程的生命周期(五狀態(tài)圖)
    • Java線程的生命周期(七狀態(tài)圖)
  • 八.Java線程的主要API
  • 九.Java線程的優(yōu)先級
    • 線程的優(yōu)先級
    • 表示線程優(yōu)先級的常量
    • 線程優(yōu)先級方法
  • 十.Java線程的啟動
  • 十一.Java線程的休眠
  • 十二.線程的終止
  • 十三.Object類中線程的相關(guān)高級方法
  • 十四.線程同步與synchronized
    • synchronized與互斥鎖
    • private與synchronized修飾的變量
    • synchronized兩種同步方式的優(yōu)缺點
    • 深入分析synchronized
    • 使用synchronized實現(xiàn)線程安全的懶漢式單例模式
  • 十五.Java線程死鎖問題
  • 十六.并發(fā)和并行的區(qū)別
  • 十七.致謝

一.用一句話講明白進(jìn)程和線程的關(guān)系(不甚嚴(yán)密)

操作系統(tǒng)可以同時執(zhí)行多個任務(wù),每個任務(wù)就是進(jìn)程;一個進(jìn)程可以同時執(zhí)行多個任務(wù),每個任務(wù)就是一個線程。

二.淺析進(jìn)程與線程

每個正在系統(tǒng)上運行的程序都是一個進(jìn)程。每個進(jìn)程包含一到多個線程。進(jìn)程也可能是整個程序或者是部分程序的動態(tài)執(zhí)行。線程是一組指令的集合,或者是程序的特殊段,它可以在程序里獨立執(zhí)行。也可以把它理解為代碼運行的上下文。所以線程基本上是輕量級的進(jìn)程,它負(fù)責(zé)在單個程序里執(zhí)行多任務(wù)。通常由操作系統(tǒng)負(fù)責(zé)多個線程的調(diào)度和執(zhí)行。

線程是操作系統(tǒng)能夠進(jìn)行運算調(diào)度的最小單位。它被包含在進(jìn)程之中,是進(jìn)程中的實際運作單位。一條線程指的是進(jìn)程中一個單一順序的控制流,一個進(jìn)程中可以并發(fā)多個線程,每條線程并行執(zhí)行不同的任務(wù)。在Unix System V及SunOS中也被稱為輕量進(jìn)程,但輕量進(jìn)程更多指內(nèi)核線程,而把用戶線程稱為線程。

線程是獨立調(diào)度和分派的基本單位。線程可以為操作系統(tǒng)內(nèi)核調(diào)度的內(nèi)核線程,如Win32線程;由用戶進(jìn)程自行調(diào)度的用戶線程,如Linux平臺的POSIX Thread;或者由內(nèi)核與用戶進(jìn)程,如Windows 7的線程,進(jìn)行混合調(diào)度。

同一進(jìn)程中的多條線程將共享該進(jìn)程中的全部系統(tǒng)資源,如虛擬地址空間,文件描述符和信號處理等等。但同一進(jìn)程中的多個線程有各自的調(diào)用棧,自己的寄存器環(huán)境,自己的線程本地存儲。

線程和進(jìn)程的區(qū)別在于,子進(jìn)程和父進(jìn)程有不同的代碼和數(shù)據(jù)空間,而多個線程則共享數(shù)據(jù)空間,每個線程有自己的執(zhí)行堆棧和程序計數(shù)器為其執(zhí)行上下文.多線程主要是為了節(jié)約CPU時間,發(fā)揮利用,根據(jù)具體情況而定. 線程的運行中需要使用計算機(jī)的內(nèi)存資源和CPU。

(這里基于Java講多線程,所以并沒有過于強(qiáng)調(diào)進(jìn)程。其實,進(jìn)程是操作系統(tǒng)的“主角”,對進(jìn)程了解不足建議閱讀《操作系統(tǒng)概念》(《Operating System Concepts》),從理論上全面理解進(jìn)程。)

三.多線程

多線程,是指從軟件或者硬件上實現(xiàn)多個線程并發(fā)執(zhí)行的技術(shù)。具有多線程能力的計算機(jī)因有硬件支持而能夠在同一時間執(zhí)行多于一個線程,進(jìn)而提升整體處理性能。具有這種能力的系統(tǒng)包括對稱多處理機(jī)、多核心處理器以及芯片級多處理或同時多線程處理器。在一個程序中,這些獨立運行的程序片段叫作“線程”,利用它編程的概念就叫作“多線程處理”。

簡而言之,線程是程序中一個單一的順序控制流程。在單個程序中同時運行多個線程完成不同的工作,稱為多線程。

多線程編程的優(yōu)點:

  • 進(jìn)程之間不易共享內(nèi)存,但線程之間共享內(nèi)存非常容易。
  • 系統(tǒng)創(chuàng)建進(jìn)程時需要為該進(jìn)程重新分配系統(tǒng)資源,但創(chuàng)建線程的代價則小得多,因此使用多線程來實現(xiàn)多任務(wù)并發(fā)比多進(jìn)程效率高。
  • Java語言內(nèi)置了多線程功能的支持,而不是單純地作為底層操作系統(tǒng)的調(diào)度方式,從而簡化了Java的多線程編程。

四.Java中的線程是什么樣子的

Java程序是通過線程執(zhí)行的,線程在程序中具有獨立的執(zhí)行路徑。當(dāng)多條線程執(zhí)行時,它們的路徑可以不同。

每一個Java應(yīng)用程序都需要有一個執(zhí)行main()函數(shù)的默認(rèn)主線程。應(yīng)用程序也可以創(chuàng)建線程在后臺操作時間密集型任務(wù),以確保對用戶的響應(yīng)。這些封裝了代碼執(zhí)行序列的線程對象就被成為runnable。

JVM給了每個線程分配了獨立的JVM棧空間以免互相干擾。獨立的棧使得線程可以追蹤他們自己下一條將要執(zhí)行的指令,這些指令會依線程的不同而有所區(qū)別。棧空間也為每條線程單獨準(zhǔn)備了一份方法參數(shù)、局部變量以及返回值的拷貝。

Java主要是基于java.lang.Thread類以及java.lang.Runnable接口來實現(xiàn)基本的線程機(jī)制的。

Thread類為底層操作系統(tǒng)的線程體系架構(gòu)提供一套統(tǒng)一的接口(通常OS負(fù)責(zé)創(chuàng)建和管理線程)。操作系統(tǒng)線程和Thread對象關(guān)聯(lián)(具體怎么關(guān)聯(lián)關(guān)系還要看OS的設(shè)計)。

Runnable接口則為關(guān)聯(lián)Thread對象的線程提供執(zhí)行代碼。這些代碼放在Runnable的void run()方法中,這個方法雖然不接收任何參數(shù)且沒有返回值,但有可能拋出異常。

五.java.lang.Thread & java.lang.Runnable

Thread


這個類里面有大量不常見的關(guān)鍵詞:

  • volatile
  • native
  • synchronized

Runnable

package java.lang;@FunctionalInterface public interface Runnable {public abstract void run(); }

我們?nèi)サ糇⑨?#xff0c;不算空行,其實Runnable接口只有5行:

  • 定義包名。
  • 注解表明函數(shù)式接口。
  • 定義接口名為Runnable。
  • 定義抽象方法run(),返回值無。
  • 類代碼段結(jié)束。
  • 使用run()方法——線程運行體

    要將一段代碼(線程體)在一個新的線程上運行,該代碼應(yīng)該在一個線程類的run()函數(shù)中。

    • 寫一個類implements Runnable接口,就必須重寫Runnable接口中的run()方法
    • 寫一個類extends Thread類,就應(yīng)該重寫Thread類的run()方法

    六.進(jìn)程的生命周期(五狀態(tài)圖)

    下圖為進(jìn)程的五狀態(tài)圖:

    七.線程的生命周期

    Java線程的生命周期(五狀態(tài)圖)

    Java線程的生命周期(七狀態(tài)圖)


    八.Java線程的主要API

    方法功能
    isAlive()判斷線程是否還未被終止
    getPriority()獲取線程優(yōu)先級
    setPriority()設(shè)置線程優(yōu)先級
    Thread.sleep()線程休眠
    join()等待調(diào)用線程運行的結(jié)束,再執(zhí)行當(dāng)前線程
    yield()讓出資源,進(jìn)入就緒隊列等候

    九.Java線程的優(yōu)先級

    線程的優(yōu)先級

    • Java提供一個線程調(diào)度器來監(jiān)控程序中啟動后進(jìn)入就緒狀態(tài)的所有線程,線程調(diào)度器按照線程的優(yōu)先級來決定應(yīng)調(diào)度哪個線程來執(zhí)行
    • Java線程的優(yōu)先級用1~10的整數(shù)來表示,越小則優(yōu)先級越低
    • Java的優(yōu)先級是高度依賴于操作系統(tǒng)的實現(xiàn)的

    表示線程優(yōu)先級的常量

    Thread類有三個常量,表示常用的線程優(yōu)先級:

    • Thread.MIN_PRIORITY //1
    • Thread.NORM_PRIORITY // 5
    • Thread.MAX_PRIORITY // 10

    線程默認(rèn)是NORM_PRIORITY,優(yōu)先級為5,包括main()線程。

    線程優(yōu)先級方法

    • getPriority():確定線程的優(yōu)先級
    • setPriority():設(shè)置線程的優(yōu)先級

    十.Java線程的啟動

    run()方法內(nèi)是線程執(zhí)行的代碼段,但一定要記住:不是用run()啟動線程!!!

    應(yīng)該用start()啟動!!!

    十一.Java線程的休眠

    與線程休眠有關(guān)的方法有三個:

    • sleep()
      • 讓線程中止一段時間的靜態(tài)方法
      • Thread.sleep(long millis):暫時停止執(zhí)行millis毫秒
      • 在睡眠期滿的瞬間,再次調(diào)用該線程不一定會恢復(fù)它的執(zhí)行,因為它很可能在等待隊列中
    • join()
      • 導(dǎo)致當(dāng)前線程等待,直到調(diào)用這個 join 方法的線程終止
      • join( )
      • join(long millis)
      • join(long millis,int nanos)
    • yield()
      • 為其他可運行的線程提供執(zhí)行機(jī)會
      • 靜態(tài)方法 — Thread.yield( )

    十二.線程的終止

    • 自動終止:一個線程完成執(zhí)行后,不能再次運行
    • 手動終止:
      • stop():已過時,基本不用
      • interrupt(): 粗暴的終止方式
      • 可通過使用一個標(biāo)志指示 run() 退出,從而終止線程

    十三.Object類中線程的相關(guān)高級方法

    • void wait():導(dǎo)致當(dāng)前的線程等待,直到其他線程調(diào)用此對象的 notify()方法或 notifyAll() 方法
    • void notify():喚醒在此對象監(jiān)視器上等待的單個線程
    • void notifyAll():喚醒在此對象監(jiān)視器上等待的所有線程

    十四.線程同步與synchronized

    線程同步最簡單的方法是使用synchronized關(guān)鍵詞。

    該關(guān)鍵詞可以用于修飾變量或者方法。

    • synchronized修飾變量:synchronized (obj){// 需要被同步的代碼 }
    • synchronized修飾方法:public synchronized void function(){//同步方法的內(nèi)容 }

    synchronized與互斥鎖

    在Java語言中,引入了對象互斥鎖的概念,來保證共享數(shù)據(jù)操作的完整性

    • 每個對象都對應(yīng)于一個可稱為“互斥鎖”的標(biāo)記,這個標(biāo)記用來保證在任一時刻,只能有一個線程訪問該對象
    • 關(guān)鍵字synchronized來與對象的互斥鎖聯(lián)系。當(dāng)某個對象用synchronized修飾時,表明該對象在任一時刻只能由一個線程訪問
    • 同步的局限性:導(dǎo)致程序的執(zhí)行效率要降低
    • 同步方法(非靜態(tài)的)的鎖為this
    • 同步方法(靜態(tài)的)的鎖為當(dāng)前類本身

    private與synchronized修飾的變量

    受到synchronized保護(hù)的程序代碼塊和方法中,要訪問的對象屬性必須設(shè)定為private,因為如果不設(shè)定為private,那么就可以用不同的方式來訪問它,這樣就達(dá)不到保護(hù)的效果了。

    synchronized兩種同步方式的優(yōu)缺點

    • synchronized方法
      優(yōu)點:

      • 可以顯示的知道哪些方法是被synchronized關(guān)鍵字保護(hù)的

      缺點:

      • 方法中有些內(nèi)容是不需要同步的,如果該方法執(zhí)行會花很長時間,那么其他人就要花較多時間等待鎖被歸還
      • 只能取得自己對象的鎖,有時候程序設(shè)計的需求,可能會需要取得其他對象的鎖
    • synchronized代碼塊
      優(yōu)點:

      • 可以針對某段程序代碼同步,不需要浪費時間在別的程序代碼上
      • 可以取得不同對象的鎖

      缺點:

      • 無法顯示的得知哪些方法是被synchronized關(guān)鍵字保護(hù)的

    深入分析synchronized

    synchronized關(guān)鍵詞實際上使用管程ADT實現(xiàn),原先效率很低,Java的幾個重要版本中經(jīng)歷不斷優(yōu)化已經(jīng)好很多了,但還是慢。

    個人覺得大家可以這么去理解synchronized:所謂多線程程序,其實是巧妙地利用了多核系統(tǒng)的并發(fā)并行,并發(fā)與并行對其很重要。但是,synchronized與所謂管程(操作系統(tǒng)的概念),正是對這里開刀,它不給你控制的機(jī)會,直接保證臨界區(qū)(操作系統(tǒng)的概念)代碼段的執(zhí)行從并發(fā)、并行到串行,一次只能走一條線程。它相當(dāng)于一種悲觀鎖,直接粗暴地化并發(fā)、并行為串行,保證了并發(fā)程序的同步與共享數(shù)據(jù)一致性。

    使用synchronized實現(xiàn)線程安全的懶漢式單例模式

    public class Singleton {private static Singleton instance = null;private Singleton() {} public static Singleton getInstance() { if(instance == null) { synchronized(Singleton.class) { if(instance == null) { instance = new Singleton(); } } } return instance; } }

    測試類:

    public class SingletonTest { public static void main(String[] args) { Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1==s2); } }

    十五.Java線程死鎖問題

    (不規(guī)范解釋) 死鎖:兩個線程,彼此在等待對方釋放其持有的鎖,而陷入無線等待。

    鎖的歸還幾種方式:

    • 基本上執(zhí)行完同步的程序代碼后,鎖就會自動歸還
    • 用break語句跳出同步的語句塊,不過這對于寫在方法聲明的 synchronized沒有作用
    • 遇到return語句
    • 遇到異常

    十六.并發(fā)和并行的區(qū)別

    薦讀:《并發(fā)和并行的區(qū)別》

    十七.致謝

    • 感謝@碼農(nóng)云帆哥的指正,已改

    總結(jié)

    以上是生活随笔為你收集整理的【Java】撩开Java线程的“神秘面纱”的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。