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

JAVA 自定義線程池的最大線程數(shù)設(shè)置方法

 更新時(shí)間:2020年06月28日 10:27:04   作者:你的龍兒  
這篇文章主要介紹了JAVA 自定義線程池的最大線程數(shù)設(shè)置方法,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下

一:CPU密集型:

  定義:CPU密集型也是指計(jì)算密集型,大部分時(shí)間用來做計(jì)算邏輯判斷等CPU動(dòng)作的程序稱為CPU密集型任務(wù)。該類型的任務(wù)需要進(jìn)行大量的計(jì)算,主要消耗CPU資源。  這種計(jì)算密集型任務(wù)雖然也可以用多任務(wù)完成,但是任務(wù)越多,花在任務(wù)切換的時(shí)間就越多,CPU執(zhí)行任務(wù)的效率就越低,所以,要最高效地利用CPU,計(jì)算密集型任務(wù)同時(shí)進(jìn)行的數(shù)量應(yīng)當(dāng)?shù)扔贑PU的核心數(shù)。

  特點(diǎn):

       01:CPU 使用率較高(也就是經(jīng)常計(jì)算一些復(fù)雜的運(yùn)算,邏輯處理等情況)非常多的情況下使用

       02:針對(duì)單臺(tái)機(jī)器,最大線程數(shù)一般只需要設(shè)置為CPU核心數(shù)的線程個(gè)數(shù)就可以了

       03:這一類型多出現(xiàn)在開發(fā)中的一些業(yè)務(wù)復(fù)雜計(jì)算和邏輯處理過程中。

  代碼示例:

package pool;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Demo02 {
 public static void main(String[] args) {
  //自定義線程池! 工作中只會(huì)使用 ThreadPoolExecutor

  /**
   * 最大線程該如何定義(線程池的最大的大小如何設(shè)置!)
   * 1、CPU 密集型,幾核,就是幾,可以保持CPU的效率最高!
   */

  //獲取電腦CPU核數(shù)
  System.out.println(Runtime.getRuntime().availableProcessors()); //8核

  ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
    2,               //核心線程池大小
    Runtime.getRuntime().availableProcessors(), //最大核心線程池大?。–PU密集型,根據(jù)CPU核數(shù)設(shè)置)
    3,               //超時(shí)了沒有人調(diào)用就會(huì)釋放
    TimeUnit.SECONDS,        //超時(shí)單位
    new LinkedBlockingDeque<>(3),     //阻塞隊(duì)列
    Executors.defaultThreadFactory(),    //線程工廠,創(chuàng)建線程的,一般不用動(dòng)
    new ThreadPoolExecutor.AbortPolicy());  //銀行滿了,還有人進(jìn)來,不處理這個(gè)人的,拋出異常

  try {
   //最大承載數(shù),Deque + Max (隊(duì)列線程數(shù)+最大線程數(shù))
   //超出 拋出 RejectedExecutionException 異常
   for (int i = 1; i <= 9; i++) {
    //使用了線程池之后,使用線程池來創(chuàng)建線程
    threadPool.execute(()->{
     System.out.println(Thread.currentThread().getName()+" ok");
    });
   }
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   //線程池用完,程序結(jié)束,關(guān)閉線程池
   threadPool.shutdown();  //(為確保關(guān)閉,將關(guān)閉方法放入到finally中)
  }
 }
}

二:IO密集型:

  定義:IO密集型任務(wù)指任務(wù)需要執(zhí)行大量的IO操作,涉及到網(wǎng)絡(luò)、磁盤IO操作,對(duì)CPU消耗較少,其消耗的主要資源為IO。

    我們所接觸到的 IO ,大致可以分成兩種:磁盤 IO和網(wǎng)絡(luò) IO。

    01:磁盤 IO ,大多都是一些針對(duì)磁盤的讀寫操作,最常見的就是文件的讀寫,假如你的數(shù)據(jù)庫、 Redis 也是在本地的話,那么這個(gè)也屬于磁盤 IO。

    02:網(wǎng)絡(luò) IO ,這個(gè)應(yīng)該是大家更加熟悉的,我們會(huì)遇到各種網(wǎng)絡(luò)請(qǐng)求,比如 http 請(qǐng)求、遠(yuǎn)程數(shù)據(jù)庫讀寫、遠(yuǎn)程 Redis 讀寫等等。

       IO 操作的特點(diǎn)就是需要等待,我們請(qǐng)求一些數(shù)據(jù),由對(duì)方將數(shù)據(jù)寫入緩沖區(qū),在這段時(shí)間中,需要讀取數(shù)據(jù)的線程根本無事可做,因此可以把 CPU 時(shí)間片讓出去,直到緩沖區(qū)寫滿。

既然這樣,IO 密集型任務(wù)其實(shí)就有很大的優(yōu)化空間了(畢竟存在等待):

       CPU 使用率較低,程序中會(huì)存在大量的 I/O 操作占用時(shí)間,導(dǎo)致線程空余時(shí)間很多,所以通常就需要開CPU核心數(shù)兩倍的線程。當(dāng)線程進(jìn)行 I/O 操作 CPU 空閑時(shí),線程等待時(shí)間所占比例越高,就需要越多線程,啟用其他線程繼續(xù)使用 CPU,以此提高 CPU 的使用率;線程 CPU 時(shí)間所占比例越高,需要越少的線程,這一類型在開發(fā)中主要出現(xiàn)在一些計(jì)算業(yè)務(wù)頻繁的邏輯中。

  代碼示例:

package pool;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Demo02 {
 public static void main(String[] args) {
  //自定義線程池! 工作中只會(huì)使用 ThreadPoolExecutor

  /**
   * 最大線程該如何定義(線程池的最大的大小如何設(shè)置?。?
   * 2、IO 密集型 >判斷你程序中十分耗IO的線程
   *  程序 15個(gè)大型任務(wù) io十分占用資源! (最大線程數(shù)設(shè)置為30)
   *  設(shè)置最大線程數(shù)為十分耗io資源線程個(gè)數(shù)的2倍
   */

  //獲取電腦CPU核數(shù)
  System.out.println(Runtime.getRuntime().availableProcessors()); //8核

  ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
    2,        //核心線程池大小
    16,                //若一個(gè)IO密集型程序有15個(gè)大型任務(wù)且其io十分占用資源?。ㄗ畲缶€程數(shù)設(shè)置為 2*CPU 數(shù)目)
    3,        //超時(shí)了沒有人調(diào)用就會(huì)釋放
    TimeUnit.SECONDS,     //超時(shí)單位
    new LinkedBlockingDeque<>(3),  //阻塞隊(duì)列
    Executors.defaultThreadFactory(),    //線程工廠,創(chuàng)建線程的,一般不用動(dòng)
    new ThreadPoolExecutor.DiscardOldestPolicy()); //隊(duì)列滿了,嘗試和最早的競(jìng)爭(zhēng),也不會(huì)拋出異常

  try {
   //最大承載數(shù),Deque + Max (隊(duì)列線程數(shù)+最大線程數(shù))
   //超出 拋出 RejectedExecutionException 異常
   for (int i = 1; i <= 9; i++) {
    //使用了線程池之后,使用線程池來創(chuàng)建線程
    threadPool.execute(()->{
     System.out.println(Thread.currentThread().getName()+" ok");
    });
   }
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   //線程池用完,程序結(jié)束,關(guān)閉線程池
   threadPool.shutdown();  //(為確保關(guān)閉,將關(guān)閉方法放入到finally中)
  }
 }
}

接下來我們進(jìn)行一一分析:

1:高并發(fā)、任務(wù)執(zhí)行時(shí)間短的業(yè)務(wù),線程池線程數(shù)可以設(shè)置為CPU核數(shù)+1,減少線程上下文的切換

2:并發(fā)不高、任務(wù)執(zhí)行時(shí)間長(zhǎng)的業(yè)務(wù)這就需要區(qū)分開看了:

  a)假如是業(yè)務(wù)時(shí)間長(zhǎng)集中在IO操作上,也就是IO密集型的任務(wù),因?yàn)镮O操作并不占用CPU,所以不要讓所有的CPU閑下來,可以適當(dāng)加大線程池中的線程數(shù)目,讓CPU處理更多的業(yè)務(wù)

  b)假如是業(yè)務(wù)時(shí)間長(zhǎng)集中在計(jì)算操作上,也就是計(jì)算密集型任務(wù),這個(gè)就沒辦法了,線程池中的線程數(shù)設(shè)置得少一些,減少線程上下文的切換

(其實(shí)從一二可以看出無論并發(fā)高不高,對(duì)于業(yè)務(wù)中是否是cpu密集還是I/O密集的判斷都是需要的當(dāng)前前提是你需要優(yōu)化性能的前提下)

3:并發(fā)高、業(yè)務(wù)執(zhí)行時(shí)間長(zhǎng),解決這種類型任務(wù)的關(guān)鍵不在于線程池而在于整體架構(gòu)的設(shè)計(jì),看看這些業(yè)務(wù)里面某些數(shù)據(jù)是否能做緩存是第一步,我們的項(xiàng)目使用的時(shí)redis作為緩存(這類非關(guān)系型數(shù)據(jù)庫還是挺好的)。增加服務(wù)器是第二步(一般政府項(xiàng)目的首先,因?yàn)椴挥脤?duì)項(xiàng)目技術(shù)做大改動(dòng),求一個(gè)穩(wěn),但前提是資金充足),至于線程池的設(shè)置,設(shè)置參考 2 。最后,業(yè)務(wù)執(zhí)行時(shí)間長(zhǎng)的問題,也可能需要分析一下,看看能不能使用中間件(任務(wù)時(shí)間過長(zhǎng)的可以考慮拆分邏輯放入隊(duì)列等操作)對(duì)任務(wù)進(jìn)行拆分和解耦。

三.:總結(jié):

  01:一個(gè)計(jì)算為主的程序(CPU密集型程序),多線程跑的時(shí)候,可以充分利用起所有的 CPU 核心數(shù),比如說 8 個(gè)核心的CPU ,開8 個(gè)線程的時(shí)候,可以同時(shí)跑 8 個(gè)線程的運(yùn)算任務(wù),此時(shí)是最大效率。但是如果線程遠(yuǎn)遠(yuǎn)超出 CPU 核心數(shù)量,反而會(huì)使得任務(wù)效率下降,因?yàn)轭l繁的切換線程也是要消耗時(shí)間的。因此對(duì)于 CPU 密集型的任務(wù)來說,線程數(shù)等于 CPU 數(shù)是最好的了。

  02:如果是一個(gè)磁盤或網(wǎng)絡(luò)為主的程序(IO密集型程序),一個(gè)線程處在 IO 等待的時(shí)候,另一個(gè)線程還可以在 CPU 里面跑,有時(shí)候 CPU 閑著沒事干,所有的線程都在等著 IO,這時(shí)候他們就是同時(shí)的了,而單線程的話此時(shí)還是在一個(gè)一個(gè)等待的。我們都知道 IO 的速度比起 CPU 來是很慢的。此時(shí)線程數(shù)等于CPU核心數(shù)的兩倍是最佳的。

以上就是JAVA 自定義線程池的最大線程數(shù)設(shè)置方法的詳細(xì)內(nèi)容,更多關(guān)于JAVA 自定義線程池的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java圖形化界面實(shí)現(xiàn)登錄窗口

    java圖形化界面實(shí)現(xiàn)登錄窗口

    這篇文章主要為大家詳細(xì)介紹了java圖形化界面實(shí)現(xiàn)登錄窗口,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • [Spring MVC] -簡(jiǎn)單表單提交實(shí)例

    [Spring MVC] -簡(jiǎn)單表單提交實(shí)例

    本篇文章主要介紹了[Spring MVC] -簡(jiǎn)單表單提交實(shí)例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。
    2016-12-12
  • Java動(dòng)態(tài)規(guī)劃方式解決不同的二叉搜索樹

    Java動(dòng)態(tài)規(guī)劃方式解決不同的二叉搜索樹

    二叉搜索樹作為一個(gè)經(jīng)典的數(shù)據(jù)結(jié)構(gòu),具有鏈表的快速插入與刪除的特點(diǎn),同時(shí)查詢效率也很優(yōu)秀,所以應(yīng)用十分廣泛。本文將詳細(xì)講講二叉搜索樹的原理與實(shí)現(xiàn),需要的可以參考一下
    2022-10-10
  • Spring Boot實(shí)現(xiàn)簡(jiǎn)單的增刪改查

    Spring Boot實(shí)現(xiàn)簡(jiǎn)單的增刪改查

    這篇文章主要介紹了Spring Boot如何實(shí)現(xiàn)簡(jiǎn)單的增刪改查,幫助大家更好的理解和學(xué)習(xí)spring boot框架,感興趣的朋友可以了解下
    2020-09-09
  • 基于SpringBoot實(shí)現(xiàn)定時(shí)發(fā)送郵件過程解析

    基于SpringBoot實(shí)現(xiàn)定時(shí)發(fā)送郵件過程解析

    這篇文章主要介紹了基于SpringBoot實(shí)現(xiàn)定時(shí)發(fā)送郵件過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • java開發(fā)環(huán)境的完整搭建過程

    java開發(fā)環(huán)境的完整搭建過程

    這篇文章主要給大家介紹了關(guān)于java開發(fā)環(huán)境的完整搭建過程,文中介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • eclipse中maven的pom.xml文件中增加依賴的方法

    eclipse中maven的pom.xml文件中增加依賴的方法

    日 在Maven項(xiàng)目中,可以使用pom.xml文件來添加依賴包,本文主要介紹了eclipse中maven的pom.xml文件中增加依賴的方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • Java打包工具jar包詳解

    Java打包工具jar包詳解

    這篇文章主要介紹了Java打包工具jar包詳解,在本例中我們引入一個(gè)叫jaxen.jar的庫,并將所有以”org.jaxen”開頭的類重命名以”org.example.jaxen”開頭,具體實(shí)例代碼跟隨小編一起看看吧
    2021-10-10
  • 在SpringBoot中,如何使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用方法總結(jié)

    在SpringBoot中,如何使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用方法總結(jié)

    我們?cè)谶M(jìn)行網(wǎng)絡(luò)連接的時(shí)候,建立套接字連接是一個(gè)非常消耗性能的事情,特別是在分布式的情況下,用線程池去保持多個(gè)客戶端連接,是一種非常消耗線程的行為.那么我們?cè)撏ㄟ^什么技術(shù)去解決上述的問題呢,那么就不得不提一個(gè)網(wǎng)絡(luò)連接的利器——Netty,需要的朋友可以參考下
    2021-06-06
  • Springboot實(shí)現(xiàn)Activemq死信隊(duì)列詳解

    Springboot實(shí)現(xiàn)Activemq死信隊(duì)列詳解

    這篇文章主要介紹了Springboot實(shí)現(xiàn)Activemq死信隊(duì)列詳解,Activemq服務(wù)端配置重新投遞次數(shù)超過?MaximumRedeliveries?,則會(huì)進(jìn)入死信隊(duì)列,默認(rèn)情況,有一個(gè)死信隊(duì)列:AcitveMQ.DLQ,所有的消息都投遞到此隊(duì)列,包括過期消息,重投遞失敗消息,需要的朋友可以參考下
    2023-12-12

最新評(píng)論