成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

線程池主要參數(shù)有哪些

這篇文章主要介紹“線程池主要參數(shù)有哪些”,在日常操作中,相信很多人在線程池主要參數(shù)有哪些問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”線程池主要參數(shù)有哪些”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括宿遷網(wǎng)站建設(shè)、宿遷網(wǎng)站制作、宿遷網(wǎng)頁(yè)制作以及宿遷網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,宿遷網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶(hù)以成都為中心已經(jīng)輻射到宿遷省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶(hù)的支持與信任!

(一)什么是線程池

線程(thread)是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位。它被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)作單位,我們的程序最終都是由線程進(jìn)行運(yùn)作。在Java中,創(chuàng)建和銷(xiāo)毀線程的動(dòng)作是很消耗資源的,因此就出現(xiàn)了所謂“池化資源”技術(shù)。

線程池是池化資源技術(shù)的一個(gè)應(yīng)用,所謂線程池,顧名思義就是預(yù)先按某個(gè)規(guī)定創(chuàng)建若干個(gè)可執(zhí)行線程放入一個(gè)容器中(線程池),需要使用的時(shí)候從線程池中去取,用完之后不銷(xiāo)毀而是放回去,從而減少了線程創(chuàng)建和銷(xiāo)毀的次數(shù),達(dá)到節(jié)約資源的目的。

(二)為什么要使用線程池

2.1 降低資源消耗

前面已經(jīng)講到線程池的出現(xiàn)減少了線程創(chuàng)建和銷(xiāo)毀的次數(shù),每個(gè)線程都可以被重復(fù)利用,可執(zhí)行多個(gè)任務(wù)。

2.2 提高系統(tǒng)的響應(yīng)速度

每當(dāng)有任務(wù)到來(lái)時(shí),直接復(fù)用線程池中的線程,而不需要等待新線程的創(chuàng)建,這個(gè)動(dòng)作可以帶來(lái)響應(yīng)速度的提升

2.3 防止過(guò)多的線程搞壞系統(tǒng)

可以根據(jù)系統(tǒng)的承受能力,調(diào)整線程池中的工作線程的數(shù)量,防止因?yàn)榫€程過(guò)多服務(wù)器變慢或死機(jī)。java一個(gè)線程默認(rèn)占用空間為1M,可以想象一旦手動(dòng)創(chuàng)建線程過(guò)多極有可能導(dǎo)致內(nèi)存溢出。

(三)線程池主要參數(shù)

我們可以用Executors類(lèi)來(lái)創(chuàng)建一些常用的線程池,但是像阿里是禁止直接通過(guò)Executors類(lèi)直接創(chuàng)建線程池的,具體的原因稍后再談。

在了解Executors類(lèi)所提供的幾個(gè)線程池前,我們首先來(lái)了解一下 ThreadPoolExecutor的主要參數(shù),ThreadPoolExecutor是創(chuàng)建線程池的類(lèi),我們選取參數(shù)最多的構(gòu)造方法來(lái)看一下:

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)
名稱(chēng)類(lèi)型含義
corePoolSizeint核心線程池的大小
maximumPoolSizeint最大線程池大小
keepAliveTimelong線程最大空閑時(shí)間
unitTimeUnit時(shí)間單位
workQueueBlockingQueue<Runnable>線程等待隊(duì)列
threadFactoryThreadFactory線程創(chuàng)建工程
handlerRejectedExecutionHandler拒絕策略

3.1 corePoolSize

當(dāng)向線程池提交一個(gè)任務(wù)時(shí),如果線程池中已創(chuàng)建的線程數(shù)量小于corePoolSIze,即便存在空閑線程,也會(huì)創(chuàng)建一個(gè)新線程來(lái)執(zhí)行任務(wù),直到創(chuàng)建的線程數(shù)大于或等于corePoolSIze。

3.2 maximumPoolSize

線程池所允許的最大線程個(gè)數(shù),當(dāng)隊(duì)列滿(mǎn)了且已經(jīng)創(chuàng)建的線程數(shù)小于maximumPoolSize時(shí),會(huì)創(chuàng)建新的線程執(zhí)行任務(wù)。

3.3 keepAliveTime

當(dāng)線程中的線程數(shù)大于corePoolSIze時(shí),如果線程空閑時(shí)間大于keepAliveTime,該線程就會(huì)被銷(xiāo)毀。

3.4 unit

keepAliveTime的時(shí)間單位

3.5 workQueue

用于保存等待執(zhí)行任務(wù)的隊(duì)列

3.6 threadFactory

用于創(chuàng)建新線程。threadFactory創(chuàng)建的線程也是采用new Thread()方式,threadFactory創(chuàng)建的線程名都具有統(tǒng)一的風(fēng)格:pool-m-thread-n

3.7 handler

拒絕策略,當(dāng)線程池和隊(duì)列滿(mǎn)了之后,再加入新線程后會(huì)執(zhí)行此策略。 下面是四種線程池的拒絕策略:

AbortPolicy:中斷任務(wù)并拋出異常

DiscardPolicy:中段任務(wù)但是不拋出異常

DiscardOldestPolicy:丟棄隊(duì)列中最老的任務(wù),然后嘗試提交新任務(wù)

CallerRunsPolicy:由調(diào)用線程處理該任務(wù)

(四)線程池執(zhí)行流程

當(dāng)我們了解了ThreadPoolExecutor的七個(gè)參數(shù)后,我們就可以很快的理解線程池的流程:

線程池主要參數(shù)有哪些

當(dāng)提交任務(wù)后,首先判斷當(dāng)前線程數(shù)是否超過(guò)核心線程數(shù),如果沒(méi)超過(guò)則創(chuàng)建新線程執(zhí)行任務(wù),否則判斷工作隊(duì)列是否已滿(mǎn),如果未滿(mǎn)則將任務(wù)添加到隊(duì)列中,否則判斷線程數(shù)是否超過(guò)最大線程數(shù),如果未超過(guò)則創(chuàng)建線程執(zhí)行任務(wù),否則執(zhí)行拒絕策略。

(五)Executors提供的線程池

executors提供了許多種線程池供用戶(hù)使用,雖然很多公司禁止使用executors創(chuàng)建線程池,但是對(duì)于剛開(kāi)始解除線程池的人來(lái)說(shuō),Executors類(lèi)所提供的線程池能很好的帶你進(jìn)入多線程的世界。

5.1 newSingleThreadExecutor

ExecutorService executorService = Executors.newSingleThreadExecutor();

聽(tīng)名字就可以知道這是一個(gè)單線程的線程池,在這個(gè)線程池中只有一個(gè)線程在工作,相當(dāng)于單線程執(zhí)行所有任務(wù),此線程可以保證所有任務(wù)的執(zhí)行順序按照提交順序執(zhí)行,看構(gòu)造方法也可以看出,corePoolSize和maximumPoolSize都是1。

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

5.2 newFixedThreadPool

ExecutorService executorService = Executors.newFixedThreadPool(2);

固定長(zhǎng)度的線程池,線程池的長(zhǎng)度在創(chuàng)建時(shí)通過(guò)變量傳入。下面是newFixedThreadPool的構(gòu)造方法,corePoolSize和maximumPoolSize都是傳入的參數(shù)值

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

5.3 newCachedThreadPool

ExecutorService executorService = Executors.newCachedThreadPool();

可緩存線程池,這個(gè)線程池設(shè)定keepAliveTime為60秒,并且對(duì)最大線程數(shù)量幾乎不做控制。

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

觀察構(gòu)造方法,corePoolSize = 0,maximumPoolSize = Integer.MAX_VALUE,即線程數(shù)量幾乎無(wú)限制。設(shè)定keepAliveTime 為60秒,線程空閑60秒后自動(dòng)結(jié)束,因?yàn)樵摼€程池創(chuàng)建無(wú)限制,不會(huì)有隊(duì)列等待,所以使用SynchronousQueue同步隊(duì)列。

5.4 newScheduledThreadPool

創(chuàng)建一個(gè)定時(shí)的線程池。此線程池支持定時(shí)以及周期性執(zhí)行任務(wù)的需求。下面是newScheduledThreadPool的用法:

Thread thread1=new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"thread1");
    }
});
Thread thread2=new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"thread2");
    }
});
Thread thread3=new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"thread3");
    }
});
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
//在1000ms后執(zhí)行thread1
scheduledExecutorService.schedule(thread1,1000,TimeUnit.MILLISECONDS);
//在1000ms后每隔1000ms執(zhí)行一次thread2,如果任務(wù)執(zhí)行時(shí)間比間隔時(shí)間長(zhǎng),則延遲執(zhí)行
scheduledExecutorService.scheduleAtFixedRate(thread2,1000,1000,TimeUnit.MILLISECONDS);
//和第二種方式類(lèi)似,但下一次任務(wù)開(kāi)始的時(shí)間為:上一次任務(wù)結(jié)束時(shí)間(而不是開(kāi)始時(shí)間) + delay時(shí)間
scheduledExecutorService.scheduleWithFixedDelay(thread3,1000,1000,TimeUnit.MILLISECONDS);

(六)為什么阿里巴巴禁止程序員用Exectors創(chuàng)建線程池

如果你的idea裝了Alibaba Java Codeing Guidelines插件(推薦大家使用,有助于讓你的代碼更加規(guī)范),那么當(dāng)你寫(xiě)了Exectors創(chuàng)建線程池后會(huì)看到提示:

線程池主要參數(shù)有哪些

并且阿里將這個(gè)用法定義為Blocker,即不允許使用,而是讓人們用ThreadPoolExecutor的方式創(chuàng)建線程池。原因是通過(guò)ThreadPoolExecutor的方式,這樣的處理方式讓寫(xiě)的人更加明確線程池的運(yùn)行規(guī)則,規(guī)避資源耗盡的風(fēng)險(xiǎn)。

線程池主要參數(shù)有哪些

Executors返回的線程池對(duì)象的弊端如下:

1)FixedThreadPool和SingleThreadPool:

??允許的請(qǐng)求隊(duì)列長(zhǎng)度為Integer.MAX_VALUE,可能會(huì)堆積大量的請(qǐng)求,從而導(dǎo)致OOM。 ?? 2)CachedThreadPool:

??允許的創(chuàng)建線程數(shù)量為Integer.MAX_VALUE,可能會(huì)創(chuàng)建大量的線程,從而導(dǎo)致OOM。 ?? 下面是ThreadPoolExecutor創(chuàng)建線程池的簡(jiǎn)單例子

int corePoolSize=5;
int maximumPoolSize=10;
long keepAliveTime=30;
BlockingQueue<Runnable> blockingQueue=new ArrayBlockingQueue(2);
RejectedExecutionHandler handler=new ThreadPoolExecutor.AbortPolicy();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, blockingQueue, handler);
threadPoolExecutor.execute(thread1);

(七)在SpringBoot項(xiàng)目中使用線程池

SpringBoot對(duì)線程池又做了一層封裝,在SpringBoot中,可以通過(guò)ThreadPoolTaskExecutor類(lèi)來(lái)創(chuàng)建線程池。需要注意兩者的區(qū)別ThreadPoolExecutor時(shí)JUC包下的類(lèi),ThreadPoolTaskExecutor是springframework包下的類(lèi)。但原理都是一樣的。

7.1 項(xiàng)目搭建

首先搭建一個(gè)SpringBoot項(xiàng)目,只需要引入web依賴(lài)即可

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

7.2 配置文件配置

線程池的參數(shù)盡量寫(xiě)到配置文件里,這樣就能根據(jù)需要進(jìn)行修改,在application.properties文件中配置:

myExecutor.corePoolSize=5
myExecutor.maxPoolSize=10
myExecutor.keepAliveSeconds=30
myExecutor.allowCoreThreadTimeOut=false
myExecutor.queueCapacity=20
myExecutor.threadNamePrefix=myExecutor-

7.3 編寫(xiě)一個(gè)自己的線程池

新建一個(gè)包叫config,新建類(lèi)ExecutorConfig ,首先參數(shù)的值從配置文件中獲取,接著用ThreadPoolTaskExecutor 創(chuàng)建一個(gè)自己的線程池,注入到Bean容器中。

@Configuration
@EnableAsync
public class ExecutorConfig {

    @Value("${myExecutor.corePoolSize}")
    private int corePoolSize;
    @Value("${myExecutor.maxPoolSize}")
    private int maxPoolSize;
    @Value("${myExecutor.keepAliveSeconds}")
    private int keepAliveSeconds;
    @Value("${myExecutor.allowCoreThreadTimeOut}")
    private boolean allowCoreThreadTimeOut;
    @Value("${myExecutor.queueCapacity}")
    private int queueCapacity;
    @Value("${myExecutor.threadNamePrefix}")
    private String threadNamePrefix;

    @Bean("myExecutor")
    public Executor myExecutor(){
        ThreadPoolTaskExecutor executor=new ThreadPoolTaskExecutor();
        //核心線程數(shù)
        executor.setCorePoolSize(corePoolSize);
        //最大線程數(shù)
        executor.setMaxPoolSize(maxPoolSize);
        //線程空閑時(shí)間
        executor.setKeepAliveSeconds(keepAliveSeconds);
        //是否保留核心線程數(shù)
        executor.setAllowCoreThreadTimeOut(allowCoreThreadTimeOut);
        //隊(duì)列長(zhǎng)度
        executor.setQueueCapacity(queueCapacity);
        //拒絕策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        //設(shè)置線程名稱(chēng)前綴
        executor.setThreadNamePrefix(threadNamePrefix);
        executor.initialize();
        return executor;
    }
}

這里需要注意的是有一個(gè)方法setAllowCoreThreadTimeOut,當(dāng)傳入?yún)?shù)為true時(shí),所有線程超時(shí)后都會(huì)被銷(xiāo)毀,如果為false,只有超過(guò)核心線程數(shù)并且超時(shí)時(shí)才會(huì)被銷(xiāo)毀。

7.4 編寫(xiě)service并使用

首先寫(xiě)一個(gè)service接口:

public interface DoSomeThing {
    /**
     * 通過(guò)線程池異步執(zhí)行耗時(shí)的任務(wù)
     */
    public void doSomeThing();
}

再編寫(xiě)實(shí)現(xiàn)類(lèi):

@Service
public class DoSomeThingImpl implements DoSomeThing {

    @Override
    @Async("myExecutor")
    public void doSomeThing() {
        System.out.println(Thread.currentThread().getName()+"-in");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"-out");
    }
}

增加注解@Async("myExecutor")后,這段方法就會(huì)異步由myExecutor線程池執(zhí)行。

7.5 編寫(xiě)一個(gè)controller

新建一個(gè)IndexController,每次請(qǐng)求執(zhí)行一次doSomeThing()方法。

@RestController
public class IndexController {

    @Autowired
    private DoSomeThing doSomeThing;

    @RequestMapping(value = "/index",method = RequestMethod.GET)
    public String index(){
        doSomeThing.doSomeThing();
        return "success";
    }
}

7.6 測(cè)試

訪問(wèn)十次http://localhost:8080/index,由于設(shè)置的核心線程數(shù)是5,隊(duì)列容量是30,因此最多只會(huì)用到5個(gè)線程資源,結(jié)果如下:

線程池主要參數(shù)有哪些

到此,關(guān)于“線程池主要參數(shù)有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

當(dāng)前文章:線程池主要參數(shù)有哪些
當(dāng)前鏈接:http://jinyejixie.com/article42/jpcohc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、網(wǎng)站策劃App設(shè)計(jì)、用戶(hù)體驗(yàn)網(wǎng)站設(shè)計(jì)公司、定制開(kāi)發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

綿陽(yáng)服務(wù)器托管
海城市| 谷城县| 德惠市| 灌南县| 聊城市| 永胜县| 芷江| 大同市| 巴林左旗| 南昌县| 慈溪市| 讷河市| 冀州市| 琼中| 建水县| 盐边县| 聊城市| 邢台市| 横山县| 沛县| 正镶白旗| 红桥区| 越西县| 垦利县| 宝坻区| 平邑县| 莎车县| 乌拉特前旗| 高密市| 蓬溪县| 龙里县| 吉木萨尔县| 海门市| 庆元县| 公主岭市| 胶南市| 紫金县| 临高县| 台东市| 南木林县| 凌海市|