91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java中怎么實現多線程

發布時間:2021-06-30 17:23:43 來源:億速云 閱讀:179 作者:Leah 欄目:大數據

java中怎么實現多線程 ,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

一、概述

  • 理解多線程先要理解線程,理解線程先要理解進程。

1. 進程

  • 一個正在執行的程序。

  • 每個進程的執行都有一個執行的順序,順序是一個執行路徑,也叫一個控制單元。

2. 線程

  • 進程中獨立的控制單元稱為線程。

  • 線程控制進程的執行。

  • 進程中只要有一個線程在執行,進程就不會結束。

  • 一個進程中至少存在一個線程。

3. 多線程

  • Java 虛擬機啟動時,會有一個 java.exe 的執行程序,也就是一個進程。

  • 這個進程中至少存在一個線程負責 java 程序的執行,這個線程的運行代碼存在 main 方法中,這個線程稱之為主線程。

  • JVM 啟動時除了執行一個主線程,還會啟動負責垃圾回收機制的線程。

  • 在一個進程中有多個線程執行的方式,稱為多線程。

4. 多線程的意義

  • 多線程能讓程序產生同時運行的效果,可以提高程序執行的效率。

    • java.exe 進程執行主程序時,如果程序的代碼非常多,在堆內存中會產生很多對象,而對象調用完后就會變成垃圾。如果垃圾過多的話,可能會導致堆內存出現內存不足的現象,影響程序的運行。這種情況下,如果只有一個線程在運行處理的話,程序執行的效率非常低;如果有多個線程在幫助處理的話,程序執行的效率將大大的提高。

    • 例如:垃圾回收機制的線程在幫助進行垃圾回收的話,那堆內存空間的釋放將快很多。

    • 例如:

5. CPU 運行的原理

  • PC 上有很多程序“同時”進行,看起來好像是 CPU “同時”處理所有程序似的,其實在同一時刻,單核的 CPU 只能運行一個程序,看起來“同時”運行的效果,實際上只是 CPU 在多個線程之間做快速切換的動作而已。

  • CPU 執行哪個程序,或者說是哪個程序搶到了 CPU 的執行權,哪個程序就執行,CPU 不會只執行一個線程,執行完一個后,會執行另一個,或者說是另一個線程搶走了 CPU 的執行權。至于如何執行是由 CPU 所決定。

  • CPU 執行哪個程序,是毫無規律的,這是多線程的特性:隨機性。

    二、創建方式

  • 創建線程的方式:繼承和實現。

1. 繼承

  • Java 中已經提供了對線程描述的類 —— Thread。繼承 Thread 類,重寫(覆蓋)run 方法,創建線程。

  • 步驟:

    • 啟動線程,調用 run 方法。

    • 注:如果對象直接調用 run 方法,那么就只有一個線程在執行,自定義的線程并沒有啟動。

    • 相當于創建線程。

    • 自定義代碼存儲在 run 方法中,讓線程執行。

    1. 定義類繼承 Thread;

    2. 重寫(覆蓋)Thread 中的 run 方法;

    3. 創建自定義類的實例對象;

    4. 實例對象調用線程的 start 方法。

  • 重寫(覆蓋)run 方法的原因:Thread 類用于描述線程,類中定義了一個功能,用于存儲線程要執行的代碼,存儲這個功能的就是 run 方法。總而言之,Thread 中的 run 方法用于存儲線程要執行的代碼。

  • 例如:java中怎么實現多線程

  • 結果如下

  • java中怎么實現多線程

  • 注:線程是隨機、交替執行的,每次運行的結果都不同

2. 實現

  • 使用繼承 Thread 創建線程的方式有弊端,就是如果類繼承了其它的父類,就無法使用 Thread 來創建線程,于是便有了通過實現 Runnable 接口來創建線程。實現 Runnable 接口,重寫(覆蓋)run 方法,創建線程。

  • 步驟:

    • start 方法會自動調用 Runnable 子類的 run 方法。

    • 將 Runnable 的子類對象傳遞給 Thread 的構造函數的原因:

    • 自定義的 run 方法所屬的對象是 Runnable 的子類對象,要讓線程去指定對象的 run 方法,就必須明確 run 方法所屬的對象。

    • 自定義代碼存儲在 run 方法中,讓線程執行。

    1. 定義類實現 Runnable;

    2. 重寫(覆蓋)Runnable 中的 run 方法;

    3. 通過 Thread 類創建線程對象。

    4. 將 Runnable 的子類對象作為實際參數傳遞給 Thread 的構造函數;

    5. 調用 Thread 中的 start 方法啟動線程。

  • 好處:避免了單繼承的局限性。(定義線程時,建議優先使用)

  • 例如:

  • java中怎么實現多線程

  • 結果如下:

  • java中怎么實現多線程

  • 注:線程是隨機、交替執行的,每次運行的結果都不同。

三、區別及狀態

1. 創建方式的區別

  • 繼承:線程代碼存儲在 Thread 子類的 run 方法中。

  • 實現:線程代碼存儲在 Runnable 子類的 run 方法中。

2. 狀態

  • 被創建:等待啟動,調用 start 啟動。

  • 運行狀態:具有執行資格和執行權。

  • 臨時狀態(阻塞):具有執行資格,但沒有執行權。

  • 凍結狀態:遇到 sleep(time) 方法和 wait() 方法時,失去執行資格和執行權;sleep 方法的時間結束或調用 notify() 方法時,獲得執行資格,變為臨時狀態(阻塞)。

  • 消亡狀態:調用 stop() 方法或 run 方法結束。

    • 注:線程從創建狀態到了運行狀態后,再次調用 start() 方法時,已經沒有任何意義,Java 運行時會提示線程狀態異常。

    •  

 java中怎么實現多線程

四、安全問題

1. 原因

  • 當多條語句操作同一個線程的共享數據時,一個線程對多條語句只執行了一部分,沒執行完成時,另外的線程參與執行,會導致共享數據的錯誤異常,也就是線程的安全問題。

  • 總而言之:

    1. 線程的隨機性。

    2. 多個線程訪問出現延遲。

  • 注:線程的安全問題在理想狀態下,一般不容易出現,但是一旦出現線程的安全問題,將會對程序軟件造成非常大的影響。

2. 同步

  • 對于線程的安全問題,在對多條操作共享數據的語句時,只讓一個線程執行完,再讓下個線程去執行,每條線程在執行的過程中,其它線程都不可以參與執行。

  • Java 中提供了專業的解決辦法 —— synchronized(同步)。

  • 解決的方式:同步代碼塊和同步函數。(均是使用關鍵字 synchronized 實現)

    • 格式:

      synchronized(對象){ 
          需要被同步的代碼;
       }


    • 同步之所以可以解決線程的安全問題,根本原因在于對象上,對象如果加了同步鎖,持有鎖的線程可以在同步中執行,沒持有鎖的線程即使獲取 CPU 的執行權,也無法進入去執行,因為沒有獲取到同步鎖。

    • 例如:

    1. 同步代碼塊

java中怎么實現多線程

  • 前提:

    1. 必須有兩個或以上的線程;

    2. 必須是多個線程使用同一個鎖。

  • 利與弊:

    • 利:解決了多線程的安全問題。

    • 弊:多個線程均需要判斷鎖,消耗資源,影響效率。

  • 如何尋找多線程的安全問題?

    1. 明確共享數據;

    2. 明確哪些代碼是多線程運行的代碼;

    3. 明確多線程運行的代碼中哪些語句是操作共享數據的。

3. 靜態函數的同步

  • 同步函數被靜態所修飾后,使用的同步鎖不再是 this,因為靜態函數中不可以定義 this,靜態進入內存時,內存中沒有本類對象,但一定存在類所對應的字節碼文件對象。

    • 例如:類名.class(對象的類型是 Class)

  • 靜態函數所使用的同步鎖就是所在類的字節碼文件對象。

    • 類名.class

  • 例如:

 java中怎么實現多線程

4. 死鎖

  • 同步中嵌套同步時,有可能出現死鎖現象。

  • 例如:

 java中怎么實現多線程

說明:程序卡死,無法繼續執行。

五、通信

  • 多個線程操作同一個資源,但是操作的動作不相同,就是線程間通信。

  • 同步操作同一個資源

    • 例如:

 java中怎么實現多線程

  • 問題點:

    • 需要喚醒對方線程時,如果只用 notify(),容易出現只喚醒本方線程的情況,會導致程序中所有線程都處于等待狀態。

    • wait():釋放 CPU 的執行權,釋放同步鎖。

    • sleep():釋放 CPU 的執行權,不釋放同步鎖。

    • 例如:同一個鎖上 wait 的線程,只能被同一個鎖上的 notify 喚醒。

    1. 這些方法存在于同步中;

    2. 使用這些方法時必須要有標識所屬的同步鎖;

    3. 鎖可以是任意的對象,任意對象調用的方法一定要定義在 Object 類中。

    1. wait()、notify()、notifyAll() 用來操作線程的,為什么是定義在 Object 類中呢?

    2. wait() 和 sleep() 有什么區別呢?

    3. 為什么要定義 notifyAll()?

JDK 5 及以上版本中提供了多線程同步鎖的升級解決方案

  • 將 synchronized(同步)替換成 Lock,將 Object 類中的 wait()、notify()、notifyAll() 替換成 Condition 對象。

  • Condition 對象可通過 Lock(鎖)進行獲取,并且支持多個相關的 Condition 對象。

  • 例如:

  •  

 java中怎么實現多線程

java中怎么實現多線程

  • 說明:只要在主函數或者其它線程中,對標記 flag 賦值 false,就可以讓 run() 方法結束,線程停止。

特殊情況:當線程處于凍結狀態時,無法讀取到 run() 方法中的代碼,線程就無法停止。

  • 需要對線程的凍結狀態進行清除,強制讓線程恢復運行,Thread 類中提供了 interrupt();

  • 例如:

java中怎么實現多線程 

java中怎么實現多線程

七、什么情況需要多線程?

  • 某些代碼需要同時執行時,可用單獨的線程封裝,多線程運行執行。

  • 例如

java中怎么實現多線程

八、拓展

  • join();

    • 當 A 線程執行到了 B 線程的 join(); 方法時,A 線程等待,B 線程執行完后,A 線程才繼續執行(此時的 B 線程與其它線程交替執行)。

    • 臨時加入線程去執行:

  • setPriority();

    • MIN_PRIORITY:最低優先級 1

    • MAX_PRIORITY:最高優先級 10

    • NORM_PRIORITY:默認優先級

    • 設置優先級:

  • yield();

    • 可以暫停當前線程,讓其它線程執行。

關于java中怎么實現多線程 問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

银川市| 会泽县| 韶关市| 临湘市| 东宁县| 修文县| 江口县| 上蔡县| 山阴县| 定结县| 兴山县| 乌拉特前旗| 布拖县| 南昌县| 宁陕县| 商丘市| 高陵县| 娄烦县| 安徽省| 百色市| 翼城县| 明光市| 习水县| 错那县| 乌恰县| 崇礼县| 紫金县| 孟连| 石泉县| 呈贡县| 昆明市| 湛江市| 云安县| 弋阳县| 西平县| 天台县| 白城市| 宁都县| 丹凤县| 巩义市| 安塞县|