多線程,線程池,線程的創建,線程池的參數

文章目錄

  • 多線程
    • -1 高并發
    • 〇、使用多線程的場景
      • 1. 為什么使用多線程
    • 1. 線程概述
      • 1.1 線程和進程
      • 1.2 并發和并行
      • 1.3 多線程的優勢
      • 1.4 程序運行原理
      • 1.5 主線程
    • 1.6 線程的 6 種狀態
    • 2. 線程的創建和啟動
      • 2.1 Thread類
      • 2.2創建線程有哪幾種方法
        • 2.2.1 繼承**Thread**類,重寫**Run**方法(其中**Thread**類本身也是實現了**Runnable**接口)
        • 2.2.2 實現**Runnable**接口,重寫**run**方法
        • 2.2.3 實現 **Callable** 接口,重寫 **call**方法(有返回值)
        • 2.2.4 通過線程池創建線程
    • 4 線程池的核心參數有哪些:
          • 4個參數的設計:

來談談多線程,線程的創建,

多線程

-1 高并發

參考文章: 【多線程高并發編程】二 實現多線程的幾種方式

〇、使用多線程的場景

1. 為什么使用多線程

通俗的解釋一下多線程先:

多線程用于堆積處理,就像一個大土堆,一個推土機很慢,那么10個推土機一起來處理,當然速度就快了,不過由于位置的限制,如果20個推土機,那么推土機之間會產生相互的避讓,相互摩擦,相互擁擠,反而不如10個處理的好,所以,多線程處理,線程數要開的恰當,就可以提高效率。

多線程使用的目的:

1、吞吐量:做WEB,容器幫你做了多線程,但是它只能幫你做請求層面的,簡單的說,就是一個請求一個線程(如struts2,是多線程的,每個客戶端請求創建一個實例,保證線程安全),或多個請求一個線程,如果是單線程,那只能是處理一個用戶的請求。

2、伸縮性:通過增加CPU核數來提升性能。

多線程的使用場景:

1、常見的瀏覽器、Web服務(現在寫的web是中間件幫你完成了線程的控制),web處理請求,各種專用服務器(如游戲服務器)

2、servlet多線程

3、FTP下載,多線程操作文件

4、數據庫用到的多線程

5、分布式計算

6、tomcat,tomcat內部采用多線程,上百個客戶端訪問同一個WEB應用,tomcat接入后就是把后續的處理扔給一個新的線程來處理,這個新的線程最后調用我們的servlet程序,比如doGet或者dpPost方法

7、后臺任務:如定時向大量(100W以上)的用戶發送郵件;定期更新配置文件、任務調度(如quartz),一些監控用于定期信息采集

8、自動作業處理:比如定期備份日志、定期備份數據庫

9、異步處理:如發微博、記錄日志

10、頁面異步處理:比如大批量數據的核對工作(有10萬個手機號碼,核對哪些是已有用戶)

11、數據庫的數據分析(待分析的數據太多),數據遷移

12、多步驟的任務處理,可根據步驟特征選用不同個數和特征的線程來協作處理,多任務的分割,由一個主線程分割給多個線程完成

1. 線程概述

1.1 線程和進程

? 進程是處于運行過程中的程序,并且具有一定的獨立功能,進程是系統進行資源分配和調度的一個獨立單位。

線程也被稱為輕量級進程,線程是進程的組成部分,一個進程可以擁有多個線程,一個線程必須有一個父進程。線程可以擁有自己的堆棧、自己的程序計數器和自己的局部變量,但不擁有系統資源,它與父進程的其它線程共享該進程所擁有的全部資源。一個線程可以創建和撤銷另一個線程,同一個進程中的多個線程之間可以并發執行。

1.2 并發和并行

? 并行指在同一時刻,有多條指令在多個處理器上同時執行;并發指在同一時刻只能有一條指令執行,但多個進程指令被快速輪換執行,使得在宏觀上具有多個進程同時執行的效果。

1.3 多線程的優勢

(1)進程之間不能共享內存,但線程之間共享內存卻非常容易。

(2)系統創建進程時需要為該進程重新分配系統資源,但創建線程代價小得多,因此使用多線程來實現多任務并發比多進程的效率高。

(3)java語言內置了多線程功能支持,而不是單純地作為底層操作系統的調度方式,從而簡化了java的多線程編程。

1.4 程序運行原理

? 分時調度:

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

? 搶占式調度:

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

1.5 主線程

? jvm啟動后,必然有一個執行路徑(線程)從main方法開始的,一直執行到main方法結束,這個線程在java中稱之為主線程。當程序的主線程執行時,如果遇到了循環而導致程序在指定位置停留時間過長,則無法馬上執行下面的程序,需要等待循環結束后能夠執行。

1.6 線程的 6 種狀態

就像生物從出生到長大、最終死亡的過程一樣,線程也有自己的生命周期,在 Java 中線程的生命周期中一共有 6 種狀態。

  • New(新創建)

  • Runnable(可運行)

  • Blocked(被阻塞)

  • Waiting(等待)

  • Timed Waiting(計時等待)

  • Terminated(被終止)

如果想要確定線程當前的狀態,可以通過 getState() 方法,并且線程在任何時刻只可能處于 1 種狀態。

運行狀態可能會有阻塞:

在這里插入圖片描述

2. 線程的創建和啟動

2.1 Thread類

Java使用Thread類代表線程,所有的線程對象都必須是Thread類或其子類的實例。每個線程的作用是完成一定的任務,實際上就是執行一段程序流。Java使用縣城執行體來表示這段流。

2.2創建線程有哪幾種方法

2.2.1 繼承Thread類,重寫Run方法(其中Thread類本身也是實現了Runnable接口)

(1)定義Thread類的子類,并重寫該類的run方法,該run方法的方法體就代表了線程要完成的任務。因此把run()方法稱為執行體。
(2)創建Thread子類的實例,即創建了線程對象。
(3)調用線程對象的start()方法來啟動該線程。

示例代碼:

package com.thread;
public class FirstThreadTest extends Thread{int i = 0;//重寫run方法,run方法的方法體就是現場執行體public void run(){for(;i<100;i++){System.out.println(getName()+"  "+i);}}public static void main(String[] args){for(int i = 0;i< 100;i++){System.out.println(Thread.currentThread().getName()+"  : "+i);if(i==20){new FirstThreadTest().start();new FirstThreadTest().start();}}}
}
2.2.2 實現Runnable接口,重寫run方法

(1)定義runnable接口的實現類,并重寫該接口的run()方法,該run()方法的方法體同樣是該線程的線程執行體。

(2)創建 Runnable實現類的實例,并依此實例作為Thread的target來創建Thread對象,該Thread對象才是真正的線程對象。

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

示例代碼:

public class RunnableThreadTest implements Runnable{private int i;public void run()	{for(i = 0;i <100;i++){System.out.println(Thread.currentThread().getName()+" "+i);}}public static void main(String[] args){for(int i = 0;i < 100;i++) {System.out.println(Thread.currentThread().getName()+" "+i);if(i==20) {RunnableThreadTest rtt = new RunnableThreadTest();new Thread(rtt,"新線程1").start();new Thread(rtt,"新線程2").start();}}}
}
2.2.3 實現 Callable 接口,重寫 call方法(有返回值)

通過Callable和Future創建線程

(1)創建Callable接口的實現類,并實現**call()方法,該call()**方法將作為線程執行體,并且有返回值。

(2)創建Callable實現類的實例,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的**call()**方法的返回值。

(3)使用FutureTask對象作為Thread對象的target創建并啟動新線程。

(4)調用FutureTask對象的get()方法來獲得子線程執行結束后的返回值

實例代碼:

package com.thread;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class CallableThreadTest implements Callable<Integer> {public static void main(String[] args) {CallableThreadTest ctt = new CallableThreadTest();FutureTask<Integer> ft = new FutureTask<>(ctt);for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName() + " 的循環變量i的值" + i);if (i == 20) {new Thread(ft, "有返回值的線程").start();}}try {System.out.println("子線程的返回值:" + ft.get());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}@Overridepublic Integer call() throws Exception {int i = 0;for (; i < 100; i++) {System.out.println(Thread.currentThread().getName() + " " + i);}return i;}}
2.2.4 通過線程池創建線程

創建線程的三種方式的對比

  1. 采用實現Runnable、Callable接口的方式創見多線程時
    優勢:
    線程類只是實現了Runnable接口或Callable接口,還可以繼承其他類。
    在這種方式下,多個線程可以共享同一個target對象,所以非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU、代碼和數據分開,形成清晰的模型,較好地體現了面向對象的思想。
    劣勢:
    編程稍微復雜,如果要訪問當前線程,則必須使用Thread.currentThread()方法。
  2. 使用繼承Thread類的方式創建多線程時
    優勢:
    編寫簡單,如果需要訪問當前線程,則無需使用Thread.currentThread()方法,直接使用this即可獲得當前線程。
    劣勢:
    線程類已經繼承了Thread類,所以不能再繼承其他父類。

4 線程池的核心參數有哪些:

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

為什么使用線程池?

使用線程池最大的原因就是可以根據系統的需求和硬件環境靈活的控制線程的數量,且可以對所有線程進行統一的管理和控制,從而提高系統的運行效率,降低系統運行運行壓力;當然了,使用線程池的原因不僅僅只有這些,我們可以從線程池自身的優點上來進一步了解線程池的好處;

使用線程池的優勢有哪些?

  1. 線程和任務分離,提升線程重用性;
  2. 控制線程并發數量,降低服務器壓力,統一管理所有線程;
  3. 提升系統響應速度,假如創建線程用的時間為T1,執行任務用的時間為T2,銷毀線程用的時間為T3,那么使用線程池就免去了T1和T3的時間;
構造方法:
public ThreadPoolExecutor(int corePoolSize, //核心線程數量int maximumPoolSize,//     最大線程數long keepAliveTime, //       最大空閑時間TimeUnit unit,         //        時間單位BlockingQueue<Runnable> workQueue,   //   任務隊列ThreadFactory threadFactory,    // 線程工廠RejectedExecutionHandler handler  //  飽和處理機制) 
{ ... }
4個參數的設計:

1:核心線程數(corePoolSize)
核心線程數的設計需要依據任務的處理時間和每秒產生的任務數量來確定,例如:執行一個任務需要0.1秒,系統百分之80的時間每秒都會產生100個任務,那么要想在1秒內處理完這100個任務,就需要10個線程,此時我們就可以設計核心線程數為10;當然實際情況不可能這么平均,所以我們一般按照8020原則設計即可,既按照百分之80的情況設計核心線程數,剩下的百分之20可以利用最大線程數處理;
2:任務隊列長度(workQueue)
任務隊列長度一般設計為:核心線程數/單個任務執行時間*2即可;例如上面的場景中,核心線程數設計為10,單個任務執行時間為0.1秒,則隊列長度可以設計為200;
3:最大線程數(maximumPoolSize)
最大線程數的設計除了需要參照核心線程數的條件外,還需要參照系統每秒產生的最大任務數決定:例如:上述環境中,如果系統每秒最大產生的任務是1000個,那么,最大線程數=(最大任務數-任務隊列長度)*單個任務執行時間;既: 最大線程數=(1000-200)*0.1=80個;
4:最大空閑時間(keepAliveTime)
這個參數的設計完全參考系統運行環境和硬件壓力設定,沒有固定的參考值,用戶可以根據經驗和系統產生任務的時間間隔合理設置一個值即可;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/165795.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/165795.shtml
英文地址,請注明出處:http://en.pswp.cn/news/165795.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

centos7 安裝docker

1.卸載舊版本&#xff0c;不管裝沒裝過&#xff0c;執行一下&#xff0c;防止版本沖突 yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine 2. yum安裝gcc相關 以及 安…

electron27-react-mateos:基于electron+react18仿matePad桌面系統

基于Electron27React18ArcoDesign搭建桌面版OS管理系統。 electron-react-mateos 基于最新前端跨端技術棧electron27.xreact18arco-designzustand4sortablejs構建的一款仿制matePad界面多層級路由管理OS系統。 ElectronReactOS支持桌面多路由配置&#xff0c;新開窗口彈窗開啟路…

YB4051系列設備是高度集成的 Li-lon 和 Li-Pol 線性充電器,針對便攜式應用的小容量電池。

YB4051H 300mA 單電池鋰離子電池充電器0.1 mA 終端&#xff0c;45nA 電池漏電流 概述&#xff1a; YB4051系列設備是高度集成的 Li-lon 和 Li-Pol 線性充電器&#xff0c;針對便攜式應用的小容量電池。它是一個完整的恒流/恒壓線性充電器。不需要外部感應電阻&#xff0c;由于…

51單片機利用I/O口高阻狀態實現觸摸控制LED燈

51單片機利用I/O口高阻狀態實現觸摸控制LED燈 1.概述 這篇文章介紹使用I/O口的高阻狀態實現一個觸摸控制LED燈亮滅的實驗。該實驗通過手觸摸P3.7引腳&#xff0c;改變電平信號控制燈的亮滅。 2.實驗過程 2.1.實驗材料 名稱型號數量單片機STC12C20521LED彩燈無1晶振12MHZ1電…

Elasticsearch:ES|QL 函數及操作符

如果你對 ES|QL 還不是很熟悉的話&#xff0c;請閱讀之前的文章 “Elasticsearch&#xff1a;ES|QL 查詢語言簡介???????”。ES|QL 提供了一整套用于處理數據的函數和運算符。 功能分為以下幾類&#xff1a; 目錄 ES|QL 聚合函數 AVG COUNT COUNT_DISTINCT 計數為近…

geemap學習筆記013:為遙感動態GIF圖添加圖名

前言 遙感動態GIF圖可以展示地理區域隨時間的變化&#xff0c;這對于監測自然災害、濕地變化、城市擴展、農田變化等方面非常有用&#xff0c;并且可以反復觀察圖像&#xff0c;以更深入地了解地表的動態變化。本節主要是對遙感動態GIF圖添加圖名&#xff0c;以便于更好地理解…

聚觀早報 |一加12正式開啟預訂;OPPO Reno11系列賣點

【聚觀365】11月24日消息 一加12正式開啟預訂 OPPO Reno11系列賣點 小鵬第三季度營收財報 Claude 2.1 聊天機器人公布 現代汽車將與倫敦大學學院合作 一加12正式開啟預訂 全新的一加12系列公開亮相已有一段時間&#xff0c;不久前一加官方宣布&#xff0c;該機將于12月4日…

android:The application could not be installed: INSTALL_FAILED_TEST_ONLY

1、問題描述 在android12 &#xff08;OPPO PEEM00&#xff09;上安裝APP時&#xff0c;提示上述異常 原因分析&#xff1a; android:testOnly&#xff1a;應用是否是為了測試&#xff0c;它可能向外暴露數據&#xff0c;引發安全漏洞。因此國內廠商的手機檢測到這個屬性為t…

ebpf實戰(一)-------監控udp延遲

問題背景: 為了分析udp數據通信中端到端的延遲,我們需要對整個通信鏈路的每個階段進行監控,找出延遲最長的階段. udp接收端有2個主要路徑 1.數據包到達本機后&#xff0c;由軟中斷處理程序將數據包接收并放入udp socket的接收緩沖區 數據接收流程 2. 應用程序調用recvmsg等a…

<JavaEE> 什么是進程控制塊(PCB Process Control Block)?

目錄 一、進程控制塊的概念 二、進程控制塊的重要屬性 2.1 唯一身份標識&#xff08;PID&#xff09; 2.2 內存指針 2.3 文件描述符表 2.4 狀態 2.5 優先級 2.6 記賬信息 2.7 上下文 一、進程控制塊的概念 進程控制塊&#xff08;Process Control Block, PCB&#xff…

Springboot引入分布式搜索引擎Es RestAPI

文章目錄 RestAPI初始化RestClient創建索引庫刪除索引庫判斷索引庫是否存在總結 RestClient操作文檔增加文檔數據查詢文檔刪除文檔修改文檔批量導入文檔小結 RestAPI ES官方提供了各種不同語言的客戶端&#xff0c;用來操作ES。這些客戶端的本質就是組裝DSL語句&#xff0c;通…

IOS Frida 常用腳本

調用堆棧 console.log("bt:" + Thread.backtrace(this.context,Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join(\n\t)); Hook 調用,修改返回值 // Get a reference to the openURL selectorvar openURL = ObjC.classes.UIApplication["- openURL:&qu…

uni-app 跨端開發注意事項

文章目錄 前言H5正常但App異常的可能性標題二H5正常但小程序異常的可能性小程序正常但App異常的可能性小程序或App正常&#xff0c;但H5異常的可能性App正常&#xff0c;小程序、H5異常的可能性使用 Vue.js 的注意區別于傳統 web 開發的注意H5 開發注意微信小程序開發注意支付寶…

Docker實用篇

Docker實用篇 0.學習目標 1.初識Docker 1.1.什么是Docker 微服務雖然具備各種各樣的優勢&#xff0c;但服務的拆分通用給部署帶來了很大的麻煩。 分布式系統中&#xff0c;依賴的組件非常多&#xff0c;不同組件之間部署時往往會產生一些沖突。在數百上千臺服務中重復部署…

STM32入門筆記15_PWR電源管理模塊

PWR和低功耗模式 PWR簡介 PWR(Power Control) 電源控制PWR負責管理STM32內部的電源供電部分&#xff0c;可以實現可編程電壓檢測器和低功耗模式的功能可編程電壓檢測器(PVD) 可以監控VDD電源電壓&#xff0c;當VDD下降到PVD閾值以下或上升到PVD閾值之上時&#xff0c;PVD會觸…

C++學習之路(一)什么是C++?如何循序漸進的學習C++?【純干貨】

C是一種高級編程語言&#xff0c;是對C語言的擴展和增強。它在C語言的基礎上添加了面向對象編程&#xff08;OOP&#xff09;的特性&#xff0c;使得開發者能夠更加靈活和高效地編寫代碼。 C的名字中的“”符號表示在C語言的基礎上向前發展一步&#xff0c;即“加加”&#x…

iOS APP包分析工具 | 京東云技術團隊

介紹 分享一款用于分析iOSipa包的腳本工具&#xff0c;使用此工具可以自動掃描發現可修復的包體積問題&#xff0c;同時可以生成包體積數據用于查看。這塊工具我們團隊內部已經使用很長一段時間&#xff0c;希望可以幫助到更多的開發同學更加效率的優化包體積問題。 工具下載…

LeeCode前端算法基礎100題(4)- 無重復字符的最長子串

一、問題詳情&#xff1a; 給定一個字符串 s &#xff0c;請你找出其中不含有重復字符的 最長子串 的長度。 示例 1: 輸入: s "abcabcbb" 輸出: 3 解釋: 因為無重復字符的最長子串是 "abc"&#xff0c;所以其長度為 3。示例 2: 輸入: s "bbbbb…

在VMware Workstation的Centos上實現KVM虛擬機的安裝部署:詳細安裝部署過程(保姆級)

KVM概述 ? 以色列qumranet公司研發&#xff0c;后被RedHad公司收購 &#xff08;1&#xff09;kvm只支持x86平臺 &#xff08;2&#xff09;依賴于 HVM,inter VT AMD-v ? KVM是&#xff08;Kernel-based Virtual Machine&#xff09;的簡稱&#xff0c;是一個開源的系統虛擬…

Spark---補充算子

一、Spark補充Transformation算子 1、join,leftOuterJoin,rightOuterJoin,fullOuterJoin 作用在K&#xff0c;V格式的RDD上。根據K進行連接&#xff0c;對&#xff08;K&#xff0c;V&#xff09;join&#xff08;K&#xff0c;W&#xff09;返回&#xff08;K&#xff0c;&a…