日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

Java為什么不建議使用Executors來(lái)創(chuàng)建線程池呢?

來(lái)源: 責(zé)編: 時(shí)間:2024-02-29 14:42:37 210觀看
導(dǎo)讀我們都知道在面試的過(guò)程中,關(guān)于線程池的問(wèn)題,一直都是面試官比較注重的考點(diǎn),現(xiàn)在也不會(huì)有面試官會(huì)選擇去問(wèn)創(chuàng)建線程都有哪些方式了,而更多的實(shí)惠關(guān)注到如何去使用線程池,今天了不起就來(lái)和大家說(shuō)說(shuō)線程池。Java創(chuàng)建線程池方

我們都知道在面試的過(guò)程中,關(guān)于線程池的問(wèn)題,一直都是面試官比較注重的考點(diǎn),現(xiàn)在也不會(huì)有面試官會(huì)選擇去問(wèn)創(chuàng)建線程都有哪些方式了,而更多的實(shí)惠關(guān)注到如何去使用線程池,今天了不起就來(lái)和大家說(shuō)說(shuō)線程池。Zhu28資訊網(wǎng)——每日最新資訊28at.com

Java創(chuàng)建線程池方式

在Java中,創(chuàng)建線程池主要使用java.util.concurrent包下的Executors類(lèi)。這個(gè)類(lèi)提供了幾種靜態(tài)工廠方法,用于創(chuàng)建和管理不同類(lèi)型的線程池。以下是一些常見(jiàn)的創(chuàng)建線程池的方式:Zhu28資訊網(wǎng)——每日最新資訊28at.com

1.Fixed Thread Pool(固定線程池)

  • 創(chuàng)建一個(gè)可重用固定線程數(shù)的線程池,以共享的無(wú)界隊(duì)列方式來(lái)運(yùn)行這些線程。在任意點(diǎn),在大多數(shù) nThreads 線程會(huì)處于處理任務(wù)的活動(dòng)狀態(tài)。如果在所有線程處于活動(dòng)狀態(tài)時(shí)提交附加任務(wù),則在有可用線程之前,附加任務(wù)將在隊(duì)列中等待。
  • 創(chuàng)建方法:Executors.newFixedThreadPool(int nThreads)

2.Cached Thread Pool(緩存線程池)

  • 創(chuàng)建一個(gè)可根據(jù)需要?jiǎng)?chuàng)建新線程的線程池,但是在以前構(gòu)造的線程可用時(shí)將重用它們。對(duì)于執(zhí)行很多短期異步任務(wù)的程序而言,這些線程池通常可提高程序性能。調(diào)用 execute 將重用以前構(gòu)造的線程(如果線程可用)。如果現(xiàn)有線程沒(méi)有可用的,則創(chuàng)建一個(gè)新線程并添加到池中。終止并從緩存中移除那些已有 60 秒鐘未被使用的線程。
  • 創(chuàng)建方法:Executors.newCachedThreadPool()

3.Single Thread Executor(單線程執(zhí)行器)

  • 創(chuàng)建一個(gè)使用單個(gè)工作線程的 Executor,以無(wú)界隊(duì)列方式來(lái)運(yùn)行該線程。(注意,如果單個(gè)線程始終因?yàn)榈却氯蝿?wù)而處于非活動(dòng)狀態(tài),則在現(xiàn)行線程終止之前,它可能無(wú)法終止。)但是,如果線程因?yàn)槭《K止,那么會(huì)有一個(gè)新的線程來(lái)替代它。單個(gè)線程的優(yōu)勢(shì)在于,你無(wú)需處理對(duì)線程生命周期的管理。
  • 創(chuàng)建方法:Executors.newSingleThreadExecutor()

4.Scheduled Thread Pool(計(jì)劃線程池)

  • 創(chuàng)建一個(gè)線程池,它可安排在給定延遲后運(yùn)行命令或者定期地執(zhí)行。
  • 創(chuàng)建方法:Executors.newScheduledThreadPool(int corePoolSize)

5.自定義線程池

除了使用Executors類(lèi)提供的靜態(tài)工廠方法創(chuàng)建線程池外,還可以通過(guò)實(shí)例化ThreadPoolExecutor類(lèi)來(lái)自定義線程池。這種方式提供了更多的靈活性,允許你設(shè)置線程池的核心參數(shù),如核心線程數(shù)、最大線程數(shù)、線程存活時(shí)間、任務(wù)隊(duì)列等。Zhu28資訊網(wǎng)——每日最新資訊28at.com

示例代碼:Zhu28資訊網(wǎng)——每日最新資訊28at.com

import java.util.concurrent.*;    public class CustomThreadPool {      public static void main(String[] args) {          int corePoolSize = 5;          int maximumPoolSize = 10;          long keepAliveTime = 60L;          TimeUnit unit = TimeUnit.SECONDS;          BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();          ThreadFactory threadFactory = Executors.defaultThreadFactory();          RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();            ThreadPoolExecutor executor = new ThreadPoolExecutor(                  corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);            // 使用線程池執(zhí)行任務(wù)...      }  }

非自定義線程池的缺點(diǎn)

我們先來(lái)看看 Executors 當(dāng)中的幾個(gè)方法,也就是上面了不起給大家寫(xiě)的除了自定義線程池的幾個(gè)方法。Zhu28資訊網(wǎng)——每日最新資訊28at.com

public static ExecutorService newFixedThreadPool(int nThreads) {        return new ThreadPoolExecutor(nThreads, nThreads,                                      0L, TimeUnit.MILLISECONDS,                                      new LinkedBlockingQueue<Runnable>());    }

在源碼中有一個(gè)類(lèi),我們明顯的看到了隊(duì)列的身影,那就是 LinkedBlockingQueue。Zhu28資訊網(wǎng)——每日最新資訊28at.com

它實(shí)現(xiàn)了一個(gè)基于鏈接節(jié)點(diǎn)的可選容量的阻塞隊(duì)列。此隊(duì)列按 FIFO(先進(jìn)先出)排序元素。隊(duì)列的頭部是在隊(duì)列中存在時(shí)間最長(zhǎng)的元素,隊(duì)列的尾部是在隊(duì)列中存在時(shí)間最短的元素。新元素總是插入到隊(duì)列的尾部,而檢索操作(如 take 和 poll)總是從隊(duì)列的頭部開(kāi)始。Zhu28資訊網(wǎng)——每日最新資訊28at.com

LinkedBlockingQueue 是一個(gè)線程安全的隊(duì)列,它內(nèi)部使用了鎖和條件變量來(lái)保證多線程環(huán)境下的正確性和一致性。因?yàn)樗亲枞?duì)列,所以它可以用于生產(chǎn)者和消費(fèi)者模型,在生產(chǎn)者線程和消費(fèi)者線程之間傳遞數(shù)據(jù)。Zhu28資訊網(wǎng)——每日最新資訊28at.com

LinkedBlockingQueue 的主要特點(diǎn)就幾個(gè)Zhu28資訊網(wǎng)——每日最新資訊28at.com

  • 容量可選
  • 阻塞操作
  • 非阻塞操作
  • 線程安全
  • 高效的并發(fā)性能

為什么說(shuō)容量可選呢?因?yàn)槲覀內(nèi)绻麊为?dú)使用這個(gè)LinkedBlockingQueue 那么你可以在創(chuàng)建 LinkedBlockingQueue 時(shí)指定一個(gè)容量,這將限制隊(duì)列中可以存儲(chǔ)的元素?cái)?shù)量。如果未指定容量,則隊(duì)列的容量將是 Integer.MAX_VALUE。當(dāng)隊(duì)列滿時(shí),任何嘗試插入元素的線程都將被阻塞,直到隊(duì)列中有空間可用。Zhu28資訊網(wǎng)——每日最新資訊28at.com

而阻塞操作則是他提供了阻塞的 put 和 take 方法。put 方法用于添加元素到隊(duì)列中,如果隊(duì)列已滿,則調(diào)用線程將被阻塞直到隊(duì)列有空閑空間。take 方法用于從隊(duì)列中移除并返回頭部元素,如果隊(duì)列為空,則調(diào)用線程將被阻塞直到隊(duì)列中有元素可用。Zhu28資訊網(wǎng)——每日最新資訊28at.com

public void put(E e) throws InterruptedException {        if (e == null) throw new NullPointerException();        // Note: convention in all put/take/etc is to preset local var        // holding count negative to indicate failure unless set.        int c = -1;        Node<E> node = new Node<E>(e);        final ReentrantLock putLock = this.putLock;        final AtomicInteger count = this.count;        ......        public E take() throws InterruptedException {        E x;        int c = -1;        final AtomicInteger count = this.count;        final ReentrantLock takeLock = this.takeLock;        takeLock.lockInterruptibly();        try {            while (count.get() == 0) {                notEmpty.await();            }            x = dequeue();            c = count.getAndDecrement();            if (c > 1).....

我們看一個(gè)使用LinkedBlockingQueue的示例:Zhu28資訊網(wǎng)——每日最新資訊28at.com

import java.util.concurrent.BlockingQueue;  import java.util.concurrent.LinkedBlockingQueue;    public class ProducerConsumerExample {      public static void main(String[] args) throws InterruptedException {          BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(5);            Thread producer = new Thread(() -> {              try {                  for (int i = 0; i < 10; i++) {                      System.out.println("Produced: " + i);                      queue.put(i);                      Thread.sleep(200); // 模擬生產(chǎn)耗時(shí)                  }              } catch (InterruptedException e) {                  Thread.currentThread().interrupt();              }          });            Thread consumer = new Thread(() -> {              try {                  while (true) {                      Integer item = queue.take();                      System.out.println("Consumed: " + item);                      Thread.sleep(500); // 模擬消費(fèi)耗時(shí)                  }              } catch (InterruptedException e) {                  Thread.currentThread().interrupt();              }          });            producer.start();          consumer.start();            producer.join();          // 注意:這里的 consumer 線程是一個(gè)無(wú)限循環(huán),所以它不會(huì)自然結(jié)束。          // 在實(shí)際應(yīng)用中,你需要有一個(gè)明確的停止條件來(lái)結(jié)束消費(fèi)者線程。      }  }

說(shuō)到這里感覺(jué)說(shuō)多了,我們回歸正題,如果我們使用標(biāo)準(zhǔn)的 newCachedThreadPool 方法,如果線程數(shù)設(shè)置和任務(wù)數(shù)不能夠配合起來(lái),就比如說(shuō)設(shè)置的線程數(shù)是一定的,這個(gè)時(shí)候,任務(wù)數(shù)量越多,就會(huì)慢慢的進(jìn)入到隊(duì)列LinkedBlockingQueue中,隊(duì)列的話,任務(wù)越多,占用的內(nèi)存越多,最終就非常容易耗盡內(nèi)存,導(dǎo)致OOM。Zhu28資訊網(wǎng)——每日最新資訊28at.com

所以我們不推薦直接使用 Executors 來(lái)創(chuàng)建線程池,但是我們更推薦使用 ThreadpoolExecutor創(chuàng)建線程池。原因就是如下的幾點(diǎn):Zhu28資訊網(wǎng)——每日最新資訊28at.com

1.資源控制:ThreadPoolExecutor 允許你明確控制并發(fā)線程的最大數(shù)量,防止因?yàn)閯?chuàng)建過(guò)多的線程而耗盡系統(tǒng)資源。通過(guò)合理地設(shè)置線程池的大小,可以平衡資源利用率和系統(tǒng)性能。Zhu28資訊網(wǎng)——每日最新資訊28at.com

2.線程復(fù)用:線程池中的線程可以被多個(gè)任務(wù)復(fù)用,這減少了在創(chuàng)建和銷(xiāo)毀線程上花費(fèi)的時(shí)間以及開(kāi)銷(xiāo),提高了系統(tǒng)的響應(yīng)速度。Zhu28資訊網(wǎng)——每日最新資訊28at.com

3.任務(wù)隊(duì)列:ThreadPoolExecutor 內(nèi)部維護(hù)了一個(gè)任務(wù)隊(duì)列,當(dāng)線程池中的線程都在工作時(shí),新提交的任務(wù)會(huì)被放在隊(duì)列中等待執(zhí)行。這提供了一種緩沖機(jī)制,可以平滑處理突發(fā)的高并發(fā)任務(wù)。Zhu28資訊網(wǎng)——每日最新資訊28at.com

4.靈活性:ThreadPoolExecutor 提供了多種配置選項(xiàng),如核心線程數(shù)、最大線程數(shù)、線程存活時(shí)間、任務(wù)隊(duì)列類(lèi)型等,這些選項(xiàng)可以根據(jù)具體的應(yīng)用場(chǎng)景進(jìn)行調(diào)整,以達(dá)到最佳的性能和資源利用率。Zhu28資訊網(wǎng)——每日最新資訊28at.com

5.異常處理:當(dāng)線程池中的線程因?yàn)槲床东@的異常而終止時(shí),ThreadPoolExecutor 會(huì)創(chuàng)建一個(gè)新的線程來(lái)替代它,從而保持線程池的穩(wěn)定性。此外,你也可以通過(guò)提供自定義的 ThreadFactory 來(lái)控制線程的創(chuàng)建過(guò)程,例如設(shè)置線程的名稱(chēng)、優(yōu)先級(jí)、守護(hù)狀態(tài)等。Zhu28資訊網(wǎng)——每日最新資訊28at.com

6.可擴(kuò)展性:ThreadPoolExecutor 的設(shè)計(jì)是基于策略的,它使用了多個(gè)接口和抽象類(lèi)來(lái)定義線程池的行為,這使得它很容易通過(guò)擴(kuò)展或替換某些組件來(lái)適應(yīng)不同的需求。Zhu28資訊網(wǎng)——每日最新資訊28at.com

7.與Java并發(fā)庫(kù)集成:ThreadPoolExecutor 是 Java 并發(fā)庫(kù) java.util.concurrent 的一部分,這個(gè)庫(kù)提供了豐富的并發(fā)工具和類(lèi),如鎖、信號(hào)量、倒計(jì)時(shí)器、阻塞隊(duì)列等,這些都可以與 ThreadPoolExecutor 無(wú)縫集成,簡(jiǎn)化多線程編程的復(fù)雜性。Zhu28資訊網(wǎng)——每日最新資訊28at.com

8.性能監(jiān)控和調(diào)優(yōu):ThreadPoolExecutor 提供了一些有用的方法,如 getTaskCount()、getCompletedTaskCount()、getPoolSize() 等,這些方法可以幫助你監(jiān)控線程池的運(yùn)行狀態(tài),從而進(jìn)行性能調(diào)優(yōu)。Zhu28資訊網(wǎng)——每日最新資訊28at.com

所以你了解了么?Zhu28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-75332-0.htmlJava為什么不建議使用Executors來(lái)創(chuàng)建線程池呢?

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 使用ConfuserEx代碼混淆工具保護(hù)你的.NET應(yīng)用程序

下一篇: 在Golang中簡(jiǎn)化日志記錄:提升性能和調(diào)試效率

標(biāo)簽:
  • 熱門(mén)焦點(diǎn)
  • K60至尊版狂暴引擎2.0加持:超177萬(wàn)跑分?jǐn)孬@性能第一

    Redmi的后性能時(shí)代戰(zhàn)略發(fā)布會(huì)今天下午如期舉辦,在本次發(fā)布會(huì)上,Redmi公布了多項(xiàng)關(guān)于和聯(lián)發(fā)科的深度合作,以及新機(jī)K60 Ultra在軟件和硬件方面的特性,例如:“K60 至尊版,雙芯旗艦
  • 5月安卓手機(jī)好評(píng)榜:魅族20 Pro奪冠

    性能榜和性價(jià)比榜之后,我們來(lái)看最后的安卓手機(jī)好評(píng)榜,數(shù)據(jù)來(lái)源安兔兔評(píng)測(cè),收集時(shí)間2023年5月1日至5月31日,僅限國(guó)內(nèi)市場(chǎng)。第一名:魅族20 Pro好評(píng)率:97.50%不得不感慨魅族老品牌還
  • 跑分安卓第一!Redmi K60至尊版8月發(fā)布!盧偉冰:目標(biāo)年度性能之王

    8月5日消息,Redmi K60至尊版將于8月發(fā)布,在此前舉行的戰(zhàn)略發(fā)布會(huì)上,官方該機(jī)將搭載搭載天璣9200+處理器,安兔兔V10跑分超177萬(wàn)分,是目前安卓陣營(yíng)最高的分?jǐn)?shù)
  • 六大權(quán)益!華為8月服務(wù)日開(kāi)啟:手機(jī)免費(fèi)貼膜、維修免人工費(fèi)

    8月5日消息,一年一度的華為開(kāi)發(fā)者大會(huì)2023(Together)日前在松山湖拉開(kāi)帷幕,與此同時(shí),華為8月服務(wù)日也式開(kāi)啟,到店可享六大專(zhuān)屬權(quán)益。華為用戶可在華為商城Ap
  • Automa-通過(guò)連接塊來(lái)自動(dòng)化你的瀏覽器

    1、前言通過(guò)瀏覽器插件可實(shí)現(xiàn)自動(dòng)化腳本的錄制與編寫(xiě),具有代表性的工具就是:Selenium IDE、Katalon Recorder,對(duì)于簡(jiǎn)單的業(yè)務(wù)來(lái)說(shuō)可快速實(shí)現(xiàn)自動(dòng)化的上手工作。Selenium IDEKat
  • 在線圖片編輯器,支持PSD解析、AI摳圖等

    自從我上次分享一個(gè)人開(kāi)發(fā)仿造稿定設(shè)計(jì)的圖片編輯器到現(xiàn)在,不知不覺(jué)已過(guò)去一年時(shí)間了,期間我經(jīng)歷了裁員失業(yè)、面試找工作碰壁,寒冬下一直沒(méi)有很好地履行計(jì)劃.....這些就放在日
  • 猿輔導(dǎo)與新東方的兩種“歸途”

    作者|卓心月 出品|零態(tài)LT(ID:LingTai_LT)如何成為一家偉大企業(yè)?答案一定是對(duì)&ldquo;勢(shì)&rdquo;的把握,這其中最關(guān)鍵的當(dāng)屬對(duì)企業(yè)戰(zhàn)略的制定,且能夠站在未來(lái)看現(xiàn)在,即使這其中的
  • 當(dāng)家的盒馬,加速謀生

    來(lái)源 | 價(jià)值星球Planet作者 | 歸去來(lái)自己&ldquo;當(dāng)家&rdquo;的盒馬,開(kāi)始加速謀生了。據(jù)盒馬官微消息,盒馬計(jì)劃今年開(kāi)放生鮮供應(yīng)鏈,將其生鮮商品送往食堂。目前,盒馬在上海已經(jīng)與
  • 阿里瓴羊One推出背后,零售企業(yè)迎數(shù)字化新解

    作者:劉曠近年來(lái)隨著數(shù)字經(jīng)濟(jì)的高速發(fā)展,各式各樣的SaaS應(yīng)用服務(wù)更是層出不窮,但本質(zhì)上SaaS大多局限于單一業(yè)務(wù)流層面,對(duì)用戶核心關(guān)切的增長(zhǎng)問(wèn)題等則沒(méi)有提供更好的解法。在Saa
Top 主站蜘蛛池模板: 顺昌县| 江川县| 揭阳市| 鄂托克旗| 汤阴县| 文昌市| 友谊县| 普宁市| 定兴县| 祁门县| 民勤县| 大石桥市| 偃师市| 灵丘县| 邻水| 西青区| 吴川市| 金阳县| 怀安县| 乌鲁木齐市| 宁波市| 岱山县| 永安市| 铁岭县| 榆社县| 类乌齐县| 陇西县| 曲阜市| 禹州市| 菏泽市| 阳信县| 平泉县| 绥宁县| 武安市| 济阳县| 武威市| 乌兰察布市| 上栗县| 达州市| 彰化县| 常州市|