線程---Day22

来源:https://www.cnblogs.com/hpcz190911/archive/2019/11/14/11854429.html
-Advertisement-
Play Games

併發與並行 併發:指兩個或多個事件在同一個時間段內發生。 並行:指兩個或多個事件在同一時刻發生(同時發生) 在操作系統中,安裝了多個程式,併發指的是在一段時間內巨集觀上有多個程式同時運行,這在單CPU系統中,每一時刻只能有一道程式執行,即微觀上這些程式是分時的交替運行,只不過是給人的感覺是同時運行,那 ...


併發與並行

  併發:指兩個或多個事件在同一個時間段內發生。

  並行:指兩個或多個事件在同一時刻發生(同時發生)

  在操作系統中,安裝了多個程式,併發指的是在一段時間內巨集觀上有多個程式同時運行,這在單CPU系統中,每一時刻只能有一道程式執行,即微觀上這些程式是分時的交替運行,只不過是給人的感覺是同時運行,那是因為分時交替運行的時間是非常短的、而在多個CPU系統中,則這些可以併發執行的程式便可以分配到多個處理器上(CPU),實現多任務並行執行, 即利用每個處理器來處理一個可以併發執行的程式,這樣多個程式便可以同時執行。目前電腦市場上說的多核 CPU,便是多核處理器,核越多,並行處理的程式越多,能大大的提高電腦運行的效率。 

線程調度

  單核處理器的電腦肯定是不能並行的處理多個任務的,只能是多個任務在單個CPU上併發運行。同理,線程也是一樣的,從巨集觀角度上理解線程是並行運行的,但是從微觀角度上分析卻是串列運行的,即一個線程一個線程的去運行,當系統只有一個CPU時,線程會以某種順序執行多個線程,我們把這種情況稱之為線程調度。 

  分類:

    分時調度:所有線程輪流使用 CPU 的使用權,平均分配每個線程占用CPU的時間。 

    搶占式調度:優先讓優先順序高的線程使用 CPU,如果線程的優先順序相同,那麼會隨機選擇一個(線程隨機性),Java使用的為搶占式調度

      搶占式調度詳解

        大部分操作系統都支持多進程併發運行,現在的操作系統幾乎都支持同時運行多個程式。比如:現在我 們上課一邊使用編輯器,一邊使用錄屏軟體,同時還開著畫圖板,dos視窗等軟體。此時,這些程式是 在同時運行,”感覺這些軟體好像在同一時刻運行著“。 實際上,CPU(中央處理器)使用搶占式調度模式在多個線程間進行著高速的切換。對於CPU的一個核而 言,某個時刻,只能執行一個線程,而 CPU的在多個線程間切換速度相對我們的感覺要快,看上去就是 在同一時刻運行。 其實,多線程程式並不能提高程式的運行速度,但能夠提高程式運行效率,讓CPU的 使用率更高。

線程與進程 

  進程:是指一個記憶體中運行的應用程式,每個進程都有一個獨立的記憶體空間,一個應用程式可以同時運行多個進程;進程也是程式的一次執行過程,是系統運行程式的基本單位;系統運行一個程式即是一個進程從創建、運行到消亡的過程。

  線程:線程是進程中的一個執行單元,負責當前進程中程式的執行,一個進程中至少有一個線程。一個進程中是可以有多個線程的,這個應用程式也可以稱之為多線程程式。 

  總之:一個程式運行後至少有一個進程,一個進程中可以包含多個線程

創建線程類 

  Java使用 java.lang.Thread 類代表線程,所有的線程對象都必須是Thread類或其子類的實例。每個線程的作用是 完成一定的任務,實際上就是執行一段程式流即一段順序執行的代碼。Java使用線程執行體來代表這段程式流。 Java中通過繼承Thread類來創建並啟動多線程的步驟如下: 

  1. 定義Thread類的子類,並重寫該類的run()方法,該run()方法的方法體就代表了線程需要完成的任務,因此把 run()方法稱為線程執行體。

  2. 創建Thread子類的實例,即創建了線程對象

  3. 調用線程對象的start()方法來啟動該線程

 1 package demosummary.thread;
 2 
 3 public class MyThread extends Thread {
 4     //定義線程名稱的構造方法
 5     public MyThread(String name) {
 6         super(name);
 7     }
 8     //重寫run方法
 9     @Override
10     public void run() {
11         for (int i = 0; i < 5; i++) {
12             System.out.println(getName() + ":正在執行第" + i + "線程");
13         }
14     }
15 
16     public static void main(String[] args) {
17         //創建線程對象
18         MyThread myThread = new MyThread("新的線程");
19         //開啟線程
20         myThread.start();
21         //執行for迴圈
22         for (int i = 0; i < 5; i++) {
23             System.out.println("正在執行主線程:"+i);
24         }
25     }
26 }

多線程原理 

 1 package demosummary.thread;
 2 
 3 public class MyThread extends Thread {
 4     //定義線程名稱的構造方法
 5     public MyThread(String name) {
 6         super(name);
 7     }
 8     //重寫run方法
 9     @Override
10     public void run() {
11         for (int i = 0; i < 5; i++) {
12             System.out.println(getName() + ":正在執行第" + i + "線程");
13         }
14     }
15 
16     public static void main(String[] args) {
17         System.out.println("這裡是main線程");
18         //創建線程對象
19         MyThread myThread = new MyThread("小強");
20         //開啟線程
21         myThread.start();
22         //執行for迴圈
23         for (int i = 0; i < 5; i++) {
24             System.out.println("旺財:"+i);
25         }
26     }
27 }

  

  程式啟動運行main時候,java虛擬機啟動一個進程,主線程main在main()調用時候被創建。隨著調用mt的對象的 start方法,另外一個新的線程也啟動了,這樣,整個應用就在多線程下運行,多線程執行時,在棧記憶體中,其實每一個執行線程都有一片自己所屬的棧記憶體空間。進行方法的壓棧和彈棧

  

Thread類

  構造方法

    public Thread() :分配一個新的線程對象。

    public Thread(String name) :分配一個指定名字的新的線程對象。

    public Thread(Runnable target) :分配一個帶有指定目標新的線程對象。

    public Thread(Runnable target,String name) :分配一個帶有指定目標新的線程對象並指定名字。

  常用方法

    public String getName() :獲取當前線程名稱。

    public void start() :導致此線程開始執行; Java虛擬機調用此線程的run方法。

    public void run() :此線程要執行的任務在此處定義代碼。

    public static void sleep(long millis) :使當前正在執行的線程以指定的毫秒數暫停(暫時停止執行)。

    public static Thread currentThread() :返回對當前正在執行的線程對象的引用。 

  創建線程方式有兩種,一種是繼承Thread類方式,一種是實現Runnable介面方式

創建線程(實現Runnable介面)

  採用 java.lang.Runnable 也是非常常見的一種,我們只需要重寫run方法即可

  方法:

    1. 定義Runnable介面的實現類,並重寫該介面的run()方法,該run()方法的方法體同樣是該線程的線程執行體。

    2. 創建Runnable實現類的實例,並以此實例作為Thread的target來創建Thread對象,該Thread對象才是真正 的線程對象。

    3. 調用線程對象的start()方法來啟動線程。

 1 package demosummary.thread;
 2 
 3 public class MyRunnable implements Runnable {
 4     //重寫run方法
 5     @Override
 6     public void run() {
 7         for (int i = 0; i < 5; i++) {
 8             System.out.println(Thread.currentThread().getName() + "---" + i);
 9         }
10     }
11 
12     public static void main(String[] args) {
13         //創建類任務對象
14         MyRunnable myRunnable = new MyRunnable();
15         //創建線程
16         Thread thread = new Thread(myRunnable, "德瑪");
17         //開啟線程
18         thread.start();
19         for (int i = 0; i < 5; i++) {
20             System.out.println("皇子" + "---" + i);
21         }
22     }
23 }

  通過實現Runnable介面,使得該類有了多線程類的特征。run()方法是多線程程式的一個執行目標。所有的多線程 代碼都在run方法裡面。Thread類實際上也是實現了Runnable介面的類。 在啟動的多線程的時候,需要先通過Thread類的構造方法Thread(Runnable target) 構造出對象,然後調用Thread 對象的start()方法來運行多線程代碼。
實際上所有的多線程代碼都是通過運行Thread的start()方法來運行的。因此,不管是繼承Thread類還是實現 Runnable介面來實現多線程,最終還是通過Thread的對象的API來控制線程的,熟悉Thread類的API是進行多線程 編程的基礎

  註意:Runnable對象僅僅作為Thread對象的target,Runnable實現類里包含的run()方法僅作為線程執行體。 而實際的線程對象依然是Thread實例,只是該Thread線程負責執行其target的run()方法

Thread和Runnable的區別

  實現Runnable介面比繼承Thread類所具有的優勢:

    1. 適合多個相同的程式代碼的線程去共用同一個資源。

    2. 可以避免java中的單繼承的局限性。

    3. 增加程式的健壯性,實現解耦操作,代碼可以被多個線程共用,代碼和線程獨立。

    4. 線程池只能放入實現Runable或Callable類線程,不能直接放入繼承Thread的類。

  註意:在java中,每次程式運行至少啟動2個線程。一個是main線程,一個是垃圾收集線程。因為每當使用 java命令執行一個類的時候,實際上都會啟動一個JVM,每一個JVM其實在就是在操作系統中啟動了一個進程

匿名內部類方式實現線程的創建

  使用線程的內匿名內部類方式,可以方便的實現每個線程執行不同的線程任務操作

 1 package demosummary.thread;
 2 
 3 public class InnerClassThread {
 4     public static void main(String[] args) {
 5         MyRunnable myRunnable = new MyRunnable(){
 6           public void run(){
 7               for (int i = 1; i <= 5; i++) {
 8                   System.out.println("德瑪---"+i);
 9               }
10           }
11         };
12         new Thread(myRunnable).start();
13     }
14 }

 


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

-Advertisement-
Play Games
更多相關文章
  • TCP三次握手和四次揮手 TCP有6種標示:SYN(建立聯機) ACK(確認) PSH(傳送) FIN(結束) RST(重置) URG(緊急) 一、TCP三次握手 第一次握手 客戶端向伺服器發出連接請求報文,這時報文首部中的同部位SYN=1,同時隨機生成初始序列號 seq=x,此時,TCP客戶端進程 ...
  • 1、Content Type 的值類型: 1.1 application/json:消息主體是序列化後的 JSON 字元串 1.2 application/x www form urlencoded:數據被編碼為名稱/值對。這是標準的編碼格式 1.3 multipart/form data: 需要在 ...
  • 一、視頻列表中控制只允許一個視頻播放 註: call() :調用一個對象的一個方法,用另一個對象替換當前對象,例如: arrayA.call(A,args1,args2) ,即 A 對象調用 arrayA 對象的方法。 二、視頻列表播放時滑動頁面抖動 註 : app 預設最小高度: min heig ...
  • 二哥,我今年大二,看你分享的《阿裡巴巴 Java 開發手冊》上有一段內容說:“迴圈體內,拼接字元串最好使用 StringBuilder 的 append 方法,而不是 + 號操作符。”到底為什麼啊,我平常一直就用的‘+’號操作符啊!二哥有空的時候能否寫一篇文章分析一下呢? 就在昨天,一位叫小菜的讀者 ...
  • 例4 水仙花數 題目描述 一個三位整數(100~999),若各位數的立方和等於該數自身,則稱其為“水仙花數”(如:153=13+53+33),找出所有的這種數。 輸入格式 沒有輸入 輸出格式 若幹行,每行1個數字。 輸入樣例 無 輸出樣例 153 * * * ... * * * (輸出被和諧了) ( ...
  • 例3 Cantor表 題目描述 現代數學的著名證明之一是Georg Cantor證明瞭有理數是可枚舉的。他是用下麵這一張表來證明這一命題的: 1/1 1/2 1/3 1/4 …… 2/1 2/2 2/3 …… 3/1 3/2 …… 4/1 …… …… 現以z字型方法給上表的每項編號。方法為:第一項是 ...
  • from flask import Flask, url_for from werkzeug.routing import BaseConverter app = Flask(__name__) # 實現一個需求: # 一個url中,含有手機號碼的變數,必須限定這個變數的字元串格式滿足手機號碼的格式 ...
  • ### url_for的基本使用: "url_for"的第一個參數應該是視圖函數的名字的字元串,後面的參數就是傳遞給"url"的。 如果傳遞的參數之前在url中已經定義了,那麼這個參數就會被當成"path"傳遞給"url"; 如果傳遞的參數之前在url中沒有定義,那麼將會被當成查詢字元串的形式放在" ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...