欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入了解Java線(xiàn)程池的原理使用及性能優(yōu)化

 更新時(shí)間:2023年04月21日 09:26:51   作者:彷徨的蝸牛  
JAVA線(xiàn)程池是一種管理和復(fù)用線(xiàn)程資源的機(jī)制,可以提高程序的效率和響應(yīng)速度。本文將介紹線(xiàn)程池的原理、使用方法和性能優(yōu)化技巧,幫助讀者深入了解和應(yīng)用JAVA線(xiàn)程池

1、什么是線(xiàn)程及線(xiàn)程池

線(xiàn)程是操作系統(tǒng)進(jìn)行時(shí)序調(diào)度的基本單元。

線(xiàn)程池可以理解為一個(gè)存在線(xiàn)程的池子,就是一個(gè)容器,這個(gè)容器只能存在線(xiàn)程。這個(gè)容器有大小,可以放7,8個(gè),也可以放3,4個(gè)。也可以把容器裝滿(mǎn),但是都有一個(gè)最大值,比如說(shuō)12個(gè)。比如說(shuō)我這邊線(xiàn)程池一般都裝5個(gè)線(xiàn)程,最多能裝12個(gè)。這個(gè)時(shí)候有五個(gè)人需要使用線(xiàn)程池,他就拿走了5個(gè)線(xiàn)程,然后在來(lái)兩個(gè)人怎么辦,他肯定沒(méi)有線(xiàn)程可以使用,他必須等著那5個(gè)人使用完才行。但是我的池子能裝12個(gè),我只有5個(gè)線(xiàn)程怎么行,我肯定還得在在裝幾個(gè)線(xiàn)程,要不然人再多一點(diǎn)就不夠了,這時(shí)候來(lái)了2個(gè),我在生產(chǎn)2個(gè)線(xiàn)程,總數(shù)到7個(gè),這個(gè)時(shí)候剩下2個(gè)人就不需要等待了,就可以直接使用。如果在來(lái)6個(gè)人呢,這個(gè)時(shí)候,我的池子里面可能只剩下5個(gè)線(xiàn)程的容量了,我能在生產(chǎn)5個(gè)線(xiàn)程但是,還有一個(gè)人得在哪等著才行。我也不能讓人家漫無(wú)目的的等著啊,我找5個(gè)凳子吧,你們坐那等著,然后第一波五個(gè)人用完線(xiàn)程結(jié)束了,一下子騰出來(lái)了5個(gè)線(xiàn)程,剩下的一個(gè)人可以使用線(xiàn)程,這個(gè)時(shí)候依次又來(lái)了10個(gè)人,我的線(xiàn)程只有4個(gè)人可以使用,位置能坐五個(gè)人,剩下一個(gè)人怎么辦,要不直接拒絕,我這邊沒(méi)有位,你要不先去別的地方看看,但是直接拒絕肯定很讓人心里不舒服,我得在想幾種拒絕策略。。。,我看我的線(xiàn)程池用的人還比較多,這么多人用,要是有人一直占著我的線(xiàn)程池怎么辦,肯定得想個(gè)辦法處理?要不就直接一個(gè)線(xiàn)程只能使用1分鐘,使用完之后立刻回收,如果想在使用,重新排隊(duì)等待。這樣我的線(xiàn)程生意越做越好,只要有人用,他就一直跑。

是不是有點(diǎn)像飯店或者是自助餐店,自助餐店是比較形象的,我的飯店里面只要有位置就可以坐人,達(dá)到最大的量,剩下的客戶(hù)只能在門(mén)口等待了,飯店里面的客戶(hù)走一個(gè),來(lái)一個(gè)在外邊等待的,如果等待的位置沒(méi)有了,客戶(hù)看看沒(méi)位置了就直接走了,如果有的人特別想吃,就在哪多等一會(huì)。在飯店里面的客戶(hù)吃的時(shí)間也不能太長(zhǎng)(一般在沒(méi)有位置的情況下),大概2個(gè)小時(shí),吃完就要離開(kāi)。

根據(jù)以上我的描述,大概可以確定線(xiàn)程池里面有什么?

裝了多少個(gè)線(xiàn)程、能裝多少線(xiàn)程、線(xiàn)程可以保留多長(zhǎng)時(shí)間、線(xiàn)程等待區(qū)、如何拒絕、創(chuàng)建線(xiàn)程

1.1、為什么要使用線(xiàn)程 

程序的運(yùn)行必須依靠進(jìn)程,進(jìn)程的實(shí)際執(zhí)行單元就是線(xiàn)程。

  • 系統(tǒng)內(nèi)服務(wù)的調(diào)用。系統(tǒng)是依托于進(jìn)程運(yùn)行的,系統(tǒng)內(nèi)有很多服務(wù),服務(wù)之間有交互,服務(wù)的運(yùn)行依托于線(xiàn)程運(yùn)行。多服務(wù)運(yùn)行依托于多線(xiàn)程運(yùn)行。服務(wù)之間的調(diào)用及數(shù)據(jù)交換是依托于進(jìn)程間的內(nèi)存進(jìn)行數(shù)據(jù)交互的,同時(shí)線(xiàn)程也可以構(gòu)建自己的內(nèi)存空間。依托于進(jìn)程間的資源調(diào)度和數(shù)據(jù)交互。
  • 多線(xiàn)程可以提高程序的執(zhí)行性能。例如,有個(gè) 90 平方的房子,一個(gè)人打掃需要花費(fèi) 30 分鐘,三個(gè)人打掃就只需要 10 分鐘,這三個(gè)人就是程序中的“多線(xiàn)程”。

在很多程序中,需要多個(gè)線(xiàn)程互相同步或互斥的并行完成工作。

線(xiàn)程相比進(jìn)程來(lái)說(shuō),更加的輕量,所以線(xiàn)程的創(chuàng)建和銷(xiāo)毀的代價(jià)變得更小。

線(xiàn)程提高了性能,雖然線(xiàn)程宏觀上是并行的,但微觀上卻是串行。從CPU角度線(xiàn)程并無(wú)法提升性能,但如果某些線(xiàn)程涉及到等待資源(比如IO,等待輸入)時(shí),多線(xiàn)程允許進(jìn)程中的其它線(xiàn)程繼續(xù)執(zhí)行而不是整個(gè)進(jìn)程被阻塞,因此提高了CPU的利用率,從這個(gè)角度會(huì)提升性能。

在多CPU或多核的情況下,使用線(xiàn)程不僅僅在宏觀上并行,在微觀上也是并行的。

1.2、為什么要使用線(xiàn)程池

多線(xiàn)程可以提高程序的執(zhí)行性能

  • 比如說(shuō)吃自助餐,當(dāng)餐位足夠多的時(shí)候,人也足夠多的時(shí)候,自助餐盈利也是最多了,同時(shí)也可以提供就餐率與客戶(hù)滿(mǎn)意度。如果有200個(gè)人吃飯,有一百個(gè)餐位的話(huà),每個(gè)人平均吃1個(gè)小時(shí),那200個(gè)人吃?xún)蓚€(gè)小時(shí)就吃完了。如果只有10個(gè)餐位的話(huà),200個(gè)人需要吃20個(gè)小時(shí)左右,想一下如果剩下的在哪里焦急等待吃飯的客戶(hù)心里多么的不開(kāi)心。
  • 自助餐餐的餐位就是線(xiàn)程,當(dāng)線(xiàn)程足夠多的時(shí)候就可以滿(mǎn)足更多的人吃飯,但是也不是說(shuō)線(xiàn)程越多越好,畢竟不是一定每次都會(huì)有200個(gè)客戶(hù)過(guò)來(lái)吃飯,就算有200個(gè)客戶(hù)過(guò)來(lái)吃飯,也需要評(píng)估一下,飯店里面的廚師夠不夠,打掃衛(wèi)生的阿姨能不能收拾過(guò)來(lái),飯店里面的盤(pán)子夠不夠等基本的硬件因素。這個(gè)就相當(dāng)于系統(tǒng)的配置一下,需要一些本質(zhì)上的內(nèi)存、CPU處理等一些硬件條件。

創(chuàng)建/銷(xiāo)毀線(xiàn)程伴隨著系統(tǒng)開(kāi)銷(xiāo),過(guò)于頻繁的創(chuàng)建/銷(xiāo)毀線(xiàn)程,會(huì)很大程度上影響處理效率(只要線(xiàn)程一直執(zhí)行就不會(huì)銷(xiāo)毀)

  • 記創(chuàng)建線(xiàn)程消耗時(shí)間T1,執(zhí)行任務(wù)消耗時(shí)間T2,銷(xiāo)毀線(xiàn)程消耗時(shí)間T3,如果T1+T3>T2,那么是不是說(shuō)開(kāi)啟一個(gè)線(xiàn)程來(lái)執(zhí)行這個(gè)任務(wù)太不劃算了!正好,線(xiàn)程池緩存線(xiàn)程,可用已有的閑置線(xiàn)程來(lái)執(zhí)行新任務(wù),避免了T1+T3帶來(lái)的系統(tǒng)開(kāi)銷(xiāo),當(dāng)然一直存活的核心線(xiàn)程也會(huì)消耗CPU資源

線(xiàn)程并發(fā)數(shù)量過(guò)多,搶占系統(tǒng)資源從而導(dǎo)致阻塞

  • 我們知道線(xiàn)程能共享系統(tǒng)資源,如果同時(shí)執(zhí)行的線(xiàn)程過(guò)多,就有可能導(dǎo)致系統(tǒng)資源不足而產(chǎn)生阻塞的情況,運(yùn)用線(xiàn)程池能有效的控制線(xiàn)程最大并發(fā)數(shù),避免以上的問(wèn)題

對(duì)線(xiàn)程進(jìn)行一些簡(jiǎn)單的管理

  • 比如:延時(shí)執(zhí)行、定時(shí)循環(huán)執(zhí)行的策略等運(yùn)用線(xiàn)程池都能進(jìn)行很好的實(shí)現(xiàn)

1.3、線(xiàn)程池的優(yōu)點(diǎn)

提高線(xiàn)程利用率

  • 保證存在業(yè)務(wù)是的時(shí)候使用,不存在業(yè)務(wù)的時(shí)候就釋放掉,合理使用線(xiàn)程,避免資源浪費(fèi)

提高程序的響應(yīng)速度

  • 由線(xiàn)程池統(tǒng)一管理的話(huà),資源分配使用統(tǒng)一的調(diào)度池進(jìn)行調(diào)度,出現(xiàn)使用線(xiàn)程的情況能避免線(xiàn)程的創(chuàng)建及銷(xiāo)毀的耗時(shí),可以直接使用線(xiàn)程。

便于統(tǒng)一管理線(xiàn)程對(duì)象

  • 線(xiàn)程池可以保證線(xiàn)程的統(tǒng)一調(diào)配與管理。

可以控制最大并發(fā)數(shù)

  • 服務(wù)器是有線(xiàn)程使用上限的,線(xiàn)程使用對(duì)資源也有很大的消耗,所以線(xiàn)程池能很好的控制線(xiàn)程資源,避免浪費(fèi)。

2、線(xiàn)程池在java中的使用

ThreadPoolExecutor這個(gè)類(lèi)是java中的線(xiàn)程池類(lèi),可以使用它進(jìn)行線(xiàn)程的池化。

// 根據(jù)上面的描述大概分析一下線(xiàn)程都需要什么及參數(shù)的解析
// corePoolSize 核心線(xiàn)程數(shù),就是上面說(shuō)的裝了多少個(gè)線(xiàn)程
// maximumPoolSize 最大線(xiàn)程數(shù),就是上面說(shuō)的能裝多少線(xiàn)程
// keepAliveTime 存活時(shí)間,就是上面說(shuō)的線(xiàn)程可以保留多長(zhǎng)時(shí)間
// TimeUnit 這個(gè)是時(shí)間單位,有時(shí)、分、秒、天等等,是存活時(shí)間的單位
// BlockingQueue<Runnable> 這是一個(gè)等待隊(duì)列,就是上面顯示的線(xiàn)程等待區(qū)
// ThreadFactory 線(xiàn)程工廠(chǎng),就是上面描述的如何創(chuàng)建線(xiàn)程,由誰(shuí)創(chuàng)建
// RejectedExecutionHandler 拒絕策略,就是上面顯示的如何拒絕,是直接拒絕還是婉拒
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                          BlockingQueue<Runnable> workQueue)
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory)
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler)
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)

可以看到,其需要如下幾個(gè)參數(shù):

  • corePoolSize(必需):核心線(xiàn)程數(shù)。默認(rèn)情況下,核心線(xiàn)程會(huì)一直存活,但是當(dāng)將 allowCoreThreadTimeout 設(shè)置為 true 時(shí),核心線(xiàn)程也會(huì)超時(shí)回收。
  • maximumPoolSize(必需):線(xiàn)程池所能容納的最大線(xiàn)程數(shù)。當(dāng)活躍線(xiàn)程數(shù)達(dá)到該數(shù)值后,后續(xù)的新任務(wù)將會(huì)阻塞。
  • keepAliveTime(必需):線(xiàn)程閑置超時(shí)時(shí)長(zhǎng)。如果超過(guò)該時(shí)長(zhǎng),非核心線(xiàn)程就會(huì)被回收。如果將 allowCoreThreadTimeout 設(shè)置為 true 時(shí),核心線(xiàn)程也會(huì)超時(shí)回收。
  • unit(必需):指定 keepAliveTime 參數(shù)的時(shí)間單位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。
  • workQueue(必需):任務(wù)隊(duì)列。通過(guò)線(xiàn)程池的 execute() 方法提交的 Runnable 對(duì)象將存儲(chǔ)在該參數(shù)中。其采用阻塞隊(duì)列實(shí)現(xiàn)。
  • threadFactory(可選):線(xiàn)程工廠(chǎng)。用于指定為線(xiàn)程池創(chuàng)建新線(xiàn)程的方式。
  • handler(可選):拒絕策略。當(dāng)達(dá)到最大線(xiàn)程數(shù)時(shí)需要執(zhí)行的飽和策略。

2.1、線(xiàn)程池的工作原理

2.2、線(xiàn)程池的java代碼示例

import java.util.concurrent.*;
public class ThreadTest {
    public static void main(String[] args) {
        ExecutorService threadPoolExecutor = new ThreadPoolExecutor(3, 5, 1L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3), Executors.defaultThreadFactory());
        for (int i = 0; i < 20; i++) {
            int finalI = i;
            threadPoolExecutor.submit( ()->{
                System.out.println(Thread.currentThread().getName() + "========" + finalI);
            });
        }
        threadPoolExecutor.shutdown();
    }
}

執(zhí)行結(jié)果:

pool-1-thread-1========0
pool-1-thread-3========2
pool-1-thread-3========4
pool-1-thread-2========1
pool-1-thread-3========5
pool-1-thread-2========8
pool-1-thread-5========7
pool-1-thread-1========3
pool-1-thread-4========6
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@61e717c2 rejected from java.util.concurrent.ThreadPoolExecutor@66cd51c3[Running, pool size = 5, active threads = 2, queued tasks = 0, completed tasks = 7]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
at com.halo.communication.ThreadTest.main(ThreadTest.java:10)

執(zhí)行的線(xiàn)程數(shù)超過(guò)了線(xiàn)程池可容納的大小,線(xiàn)程池使用默認(rèn)拒絕策略拒絕多余線(xiàn)程執(zhí)行,然后開(kāi)始出現(xiàn)異常處理。上面執(zhí)行的線(xiàn)程數(shù)到thread-5,5是線(xiàn)程池的默認(rèn)最大線(xiàn)程數(shù)。然后執(zhí)行for循環(huán)20次,進(jìn)行執(zhí)行到8的時(shí)候出現(xiàn)異常,說(shuō)明線(xiàn)程池已經(jīng)超載滿(mǎn)負(fù)荷執(zhí)行,所以線(xiàn)程池執(zhí)行拒絕策略。

到此這篇關(guān)于深入了解Java線(xiàn)程池的原理使用及性能優(yōu)化的文章就介紹到這了,更多相關(guān)Java線(xiàn)程池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • IDEA配置java開(kāi)發(fā)環(huán)境(maven、gradle、tomcat)

    IDEA配置java開(kāi)發(fā)環(huán)境(maven、gradle、tomcat)

    這篇文章主要介紹了IDEA配置java開(kāi)發(fā)環(huán)境(maven、gradle、tomcat),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(6)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(6)

    下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你
    2021-07-07
  • Java基礎(chǔ)之ClassLoader詳解

    Java基礎(chǔ)之ClassLoader詳解

    這篇文章主要介紹了Java基礎(chǔ)之ClassLoader詳解,文中對(duì)ClassLoader有非常詳細(xì)的解說(shuō),對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Java源碼解析之Iterable接口

    Java源碼解析之Iterable接口

    遍歷集合我相信大部分coder都會(huì)遇到,也經(jīng)常使用,而Java給我們提供了多種選擇,接下來(lái)就讓我們一起來(lái)看看吧,需要的朋友可以參考下
    2021-05-05
  • 設(shè)置JavaScript自動(dòng)提示-Eclipse/MyEclipse

    設(shè)置JavaScript自動(dòng)提示-Eclipse/MyEclipse

    自動(dòng)提示需要2個(gè)組件,分別是:ext-4.0.2a.jsb2||spket-1.6.16.jar,需要的朋友可以參考下
    2016-05-05
  • Springboot事件和bean生命周期執(zhí)行機(jī)制實(shí)例詳解

    Springboot事件和bean生命周期執(zhí)行機(jī)制實(shí)例詳解

    這篇文章主要介紹了Springboot事件和bean的生命周期執(zhí)行機(jī)制,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Java9 Stream Collectors新增功能(小結(jié))

    Java9 Stream Collectors新增功能(小結(jié))

    這篇文章主要介紹了Java9 Stream Collectors新增功能(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Spring boot + mybatis + orcale實(shí)現(xiàn)步驟實(shí)例代碼講解

    Spring boot + mybatis + orcale實(shí)現(xiàn)步驟實(shí)例代碼講解

    這篇文章主要介紹了Spring boot + mybatis + orcale的實(shí)現(xiàn)步驟實(shí)例代碼講解,需要的朋友可以參考下
    2017-12-12
  • 基于Maven?pom文件中屬性變量總結(jié)

    基于Maven?pom文件中屬性變量總結(jié)

    這篇文章主要介紹了Maven?pom文件中屬性變量總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java面試題解析之判斷以及防止SQL注入

    Java面試題解析之判斷以及防止SQL注入

    這篇文章主要介紹了Java面試題解析之判斷以及防止SQL注入,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02

最新評(píng)論