真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

使用Java線程池的方法步驟

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

創(chuàng)新互聯(lián)公司是專業(yè)的廣豐網(wǎng)站建設(shè)公司,廣豐接單;提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作,網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行廣豐網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

使用Java線程池的方法步驟

1.為什么使用線程池

1.頻繁創(chuàng)建和銷毀單個(gè)線程,浪費(fèi)資源,并且還會(huì)出現(xiàn)頻繁GC

2.缺乏統(tǒng)一管理,各線程相互競(jìng)爭(zhēng)

2.ThreadPoolExecutor

ThreadPoolExecutor有四個(gè)重載的構(gòu)造方法,我們這里來說說參數(shù)最多的那一個(gè)重載的構(gòu)造方法,這樣大家就知道其他方法參數(shù)的含義了,如下:

public ThreadPoolExecutor(int corePoolSize,

                              int maximumPoolSize,

                              long keepAliveTime,

                              TimeUnit unit,

                              BlockingQueue workQueue,

                              ThreadFactory threadFactory,

                              RejectedExecutionHandler handler) 

  • 各參數(shù)詳細(xì)說明:

這里是7個(gè)參數(shù)(我們?cè)陂_發(fā)中用的更多的是5個(gè)參數(shù)的構(gòu)造方法),OK,那我們來看看這里七個(gè)參數(shù)的含義:

corePoolSize 線程池中核心線程的數(shù)量

maximumPoolSize 線程池中最大線程數(shù)量

keepAliveTime 非核心線程的超時(shí)時(shí)長(zhǎng),當(dāng)系統(tǒng)中非核心線程閑置時(shí)間超過keepAliveTime之后,則會(huì)被回收。如果ThreadPoolExecutor的allowCoreThreadTimeOut屬性設(shè)置為true,則該參數(shù)也表示核心線程的超時(shí)時(shí)長(zhǎng)

unit 第三個(gè)參數(shù)的單位,有納秒、微秒、毫秒、秒、分、時(shí)、天等

workQueue 線程池中的任務(wù)隊(duì)列,該隊(duì)列主要用來存儲(chǔ)已經(jīng)被提交但是尚未執(zhí)行的任務(wù)。存儲(chǔ)在這里的任務(wù)是由ThreadPoolExecutor的execute方法提交來的。

threadFactory 為線程池提供創(chuàng)建新線程的功能,這個(gè)我們一般使用默認(rèn)即可

handler 拒絕策略,當(dāng)線程無法執(zhí)行新任務(wù)時(shí)(一般是由于線程池中的線程數(shù)量已經(jīng)達(dá)到最大數(shù)或者線程池關(guān)閉導(dǎo)致的),默認(rèn)情況下,當(dāng)線程池?zé)o法處理新線程時(shí),會(huì)拋出一個(gè)RejectedExecutionException。

  • workQueue介紹

1.ArrayBlockingQueue:這個(gè)表示一個(gè)規(guī)定了大小的BlockingQueue,ArrayBlockingQueue的構(gòu)造函數(shù)接受一個(gè)int類型的數(shù)據(jù),該數(shù)據(jù)表示BlockingQueue的大小,存儲(chǔ)在ArrayBlockingQueue中的元素按照FIFO(先進(jìn)先出)的方式來進(jìn)行存取。

2.LinkedBlockingQueue:這個(gè)表示一個(gè)大小不確定的BlockingQueue,在LinkedBlockingQueue的構(gòu)造方法中可以傳一個(gè)int類型的數(shù)據(jù),這樣創(chuàng)建出來的LinkedBlockingQueue是有大小的,也可以不傳,不傳的話,LinkedBlockingQueue的大小就為Integer.MAX_VALUE,源碼如下:

3.PriorityBlockingQueue:這個(gè)隊(duì)列和LinkedBlockingQueue類似,不同的是PriorityBlockingQueue中的元素不是按照FIFO來排序的,而是按照元素的Comparator來決定存取順序的(這個(gè)功能也反映了存入PriorityBlockingQueue中的數(shù)據(jù)必須實(shí)現(xiàn)了Comparator接口)。

4.SynchronousQueue:這個(gè)是同步Queue,屬于線程安全的BlockingQueue的一種,在SynchronousQueue中,生產(chǎn)者線程的插入操作必須要等待消費(fèi)者線程的移除操作,Synchronous內(nèi)部沒有數(shù)據(jù)緩存空間,因此我們無法對(duì)SynchronousQueue進(jìn)行讀取或者遍歷其中的數(shù)據(jù),元素只有在你試圖取走的時(shí)候才有可能存在。我們可以理解為生產(chǎn)者和消費(fèi)者互相等待,等到對(duì)方之后然后再一起離開。

  • 拒絕策略

AbortPolicy:直接拒絕,并拋出異常,這也是默認(rèn)的策略。

CallerRunsPolicy:直接讓調(diào)用execute方法的線程去執(zhí)行此任務(wù)。

DiscardOldestPolicy:丟棄最老的未處理的任務(wù),然后重新嘗試執(zhí)行當(dāng)前的新任務(wù)。

DiscardPolicy:直接丟棄當(dāng)前任務(wù),但是不拋異常

3.執(zhí)行過程

當(dāng)線程數(shù)量未達(dá)到corePoolSize的時(shí)候,就會(huì)創(chuàng)建新的線程來執(zhí)行任務(wù)。

當(dāng)核心線程數(shù)已滿,就會(huì)把任務(wù)放到阻塞隊(duì)列。

當(dāng)隊(duì)列已滿,并且未達(dá)到最大線程數(shù),就會(huì)新建非核心線程來執(zhí)行任務(wù)(重要)。

當(dāng)隊(duì)列已滿,并且達(dá)到了最大線程數(shù),則選擇一種拒絕策略來執(zhí)行。

4.其他線程池

1.FixedThreadPool

使用Java線程池的方法步驟

固定大小的線程池,可以指定線程池的大小,該線程池corePoolSize和maximumPoolSize相等,阻塞隊(duì)列使用的是LinkedBlockingQueue,大小為整數(shù)最大值。

該線程池中的線程數(shù)量始終不變,當(dāng)有新任務(wù)提交時(shí),線程池中有空閑線程則會(huì)立即執(zhí)行,如果沒有,則會(huì)暫存到阻塞隊(duì)列。對(duì)于固定大小的線程池,不存在線程數(shù)量的變化。

同時(shí)使用無界的LinkedBlockingQueue來存放執(zhí)行的任務(wù)。當(dāng)任務(wù)提交十分頻繁的時(shí)候,LinkedBlockingQueue迅速增大,存在著耗盡系統(tǒng)資源的問題。

而且在線程池空閑時(shí),即線程池中沒有可運(yùn)行任務(wù)時(shí),它也不會(huì)釋放工作線程,還會(huì)占用一定的系統(tǒng)資源,需要shutdown

2.SingleThreadExecutor

使用Java線程池的方法步驟

可以看到阻塞隊(duì)例 使用的是LinkedBolckingQueue,且默認(rèn)大小為Integer.MAX_VALUE,這樣的話,如果有大量請(qǐng)求到來,會(huì)放入到這個(gè)任務(wù)隊(duì)列里,可能會(huì)導(dǎo)致OOM;

3.Executors.newCachedThreadPool()

使用Java線程池的方法步驟

可緩存線程池,先查看線程池中有沒有以前建立的線程,如果有就直接使用,如果沒有新建一個(gè)線程加入線程池中,可緩存線程池

通常用于執(zhí)行一些生存期很短的異步型任務(wù);線程池為無限大,當(dāng)執(zhí)行當(dāng)前任務(wù)時(shí)上一個(gè)任務(wù)已經(jīng)完成,會(huì)復(fù)用執(zhí)行上一個(gè)任務(wù)的線程,而不用每次新建線程

緩存的線程默認(rèn)存活60秒。線程的核心池corePoolSize大小為0,核心池最大為Integer.MAX_VALUE,阻塞隊(duì)列使用的是SynchronousQueue。

是一個(gè)直接提交的阻塞隊(duì)列,他總會(huì)迫使線程池增加新的線程去執(zhí)行新的任務(wù)。

在沒有任務(wù)執(zhí)行時(shí),當(dāng)線程的空閑時(shí)間超過keepAliveTime(60秒),則工作線程將會(huì)終止被回收,當(dāng)提交新任務(wù)時(shí),

如果沒有空閑線程,則創(chuàng)建新線程執(zhí)行任務(wù),會(huì)導(dǎo)致一定的系統(tǒng)開銷。

如果同時(shí)又大量任務(wù)被提交,而且任務(wù)執(zhí)行的時(shí)間不是特別快,那么線程池便會(huì)新增出等量的線程池處理任務(wù),這很可能會(huì)很快耗盡系統(tǒng)的資源。

4.ScheduledThreadPool

使用Java線程池的方法步驟

創(chuàng)建一個(gè)定長(zhǎng)線程池,支持定時(shí)及周期性任務(wù)執(zhí)行

定時(shí)線程池,該線程池可用于周期性地去執(zhí)行任務(wù),通常用于周期性的同步數(shù)據(jù)。

scheduleAtFixedRate:是以固定的頻率去執(zhí)行任務(wù),周期是指每次執(zhí)行任務(wù)成功執(zhí)行之間的間隔。

schedultWithFixedDelay:是以固定的延時(shí)去執(zhí)行任務(wù),延時(shí)是指上一次執(zhí)行成功之后和下一次開始執(zhí)行的之前的時(shí)間。

5.為什么阿里推薦自定義線程池

通過上述源碼分析,我們發(fā)現(xiàn)newFixedThreadPool和newSingleThreadExecutor方法他們都使用了LinkedBlockingQueue的任務(wù)隊(duì)列,LinkedBlockingQueue的默認(rèn)大小為Integer.MAX_VALUE。而newCachedThreadPool中定義的線程池大小為Integer.MAX_VALUE。

所以阿里禁止使用Executors創(chuàng)建線程池的原因就是FixedThreadPool和SingleThreadPool的請(qǐng)求隊(duì)列長(zhǎng)度為Integer.MAX_VALUE,可能會(huì)堆積大量的請(qǐng)求,從而導(dǎo)致OOM。

CachedThreadPool允許的創(chuàng)建線程數(shù)量為Integer.MAX_VALUE,可能會(huì)創(chuàng)建大量的線程,從而導(dǎo)致OOM。

6.其他

1.shutDown() 關(guān)閉線程池,不影響已經(jīng)提交的任務(wù)

2.shutDownNow() 關(guān)閉線程池,并嘗試去終止正在執(zhí)行的線程

3.allowCoreThreadTimeOut(boolean value) 允許核心線程閑置超時(shí)時(shí)被回收

4.單例模式創(chuàng)建線程池

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.*;

/**

 * 異步任務(wù)處理器

 */

public class AsyncTaskExecutor {

    /** 線程池保持ALIVE狀態(tài)線程數(shù) */

    public static final int                 CORE_POOL_SIZE      = 10;

    /** 線程池最大線程數(shù) */

    public static final int                 MAX_POOL_SIZE       = 40;

    /** 空閑線程回收時(shí)間 */

    public static final int                 KEEP_ALIVE_TIME     = 1000;

    /** 線程池等待隊(duì)列 */

    public static final int                 BLOCKING_QUEUE_SIZE = 1000;

    /** 業(yè)務(wù)請(qǐng)求異步處理線程池 */

    private static final ThreadPoolExecutor processExecutor = new ThreadPoolExecutor(

            CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.MICROSECONDS,

            new LinkedBlockingQueue(BLOCKING_QUEUE_SIZE),

new TreadFactoryBuilder.setNameFormat("boomoom-thread-pool-%d").build(),

new TreadPoolExecutor.DiscardPolicy());

    private AsyncTaskExecutor() {}; 

    /**

     * 異步任務(wù)處理

     *

     * @param task 任務(wù)

     */

    public void execute(Runnable task) {

        processExecutor.submit(task);

    }

}

懶漢式和饑漢式區(qū)別

1.餓漢式是線程安全的,在類創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對(duì)象供系統(tǒng)使用,以后不再改變。

2.懶漢式如果想要線程安全必須用雙重檢驗(yàn)鎖并且對(duì)象還必須是volatile,防止對(duì)象指令重排

到此,關(guān)于“使用Java線程池的方法步驟”的學(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ī)砀鄬?shí)用的文章!


網(wǎng)站題目:使用Java線程池的方法步驟
文章鏈接:http://weahome.cn/article/gpehji.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部