乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

       漢無(wú)為 2018-08-26

      線程復(fù)用:線程池

      首先舉個(gè)例子:

      假設(shè)這里有一個(gè)系統(tǒng),大概每秒需要處理5萬(wàn)條數(shù)據(jù),這5萬(wàn)條數(shù)據(jù)為一個(gè)批次,而這沒(méi)秒發(fā)送的5萬(wàn)條數(shù)據(jù)數(shù)據(jù)需要經(jīng)過(guò)兩個(gè)處理過(guò)程,第一步是數(shù)據(jù)存入數(shù)據(jù)庫(kù),第二步是對(duì)數(shù)據(jù)進(jìn)行其他業(yè)務(wù)的分析,假設(shè)第一步我是用的是普通的JDBC插入數(shù)據(jù),為了不影響程序的繼續(xù)執(zhí)行,我寫了一個(gè)線程,讓這個(gè)子線程不阻塞主線程,繼續(xù)處理第二步驟的數(shù)據(jù),我們知道插入5萬(wàn)條數(shù)據(jù)大概需要2至3秒的時(shí)間,如果每一批次插入數(shù)據(jù)庫(kù)的時(shí)候,就創(chuàng)建一個(gè)線程進(jìn)行處理,可想而知,由于插入數(shù)據(jù)庫(kù)的時(shí)間較久,不能很快的處理,這樣的話,一段時(shí)間之后,系統(tǒng)中就會(huì)有很多的這種插入數(shù)據(jù)的線程(PS:只是假設(shè)場(chǎng)景,方案設(shè)計(jì)的可能不合理)。

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      如果,我們使用上述的方式去創(chuàng)建線程,使用start()方法啟動(dòng)線程,該線程會(huì)在run()方法結(jié)束后,自動(dòng)回收該線程。雖然如此,在上邊的場(chǎng)景中線程中業(yè)務(wù)的處理速度完全達(dá)不到我們的要求,系統(tǒng)中的線程會(huì)逐漸變大,進(jìn)而消耗CPU資源,大量的線程搶占寶貴的內(nèi)存資源,可能還會(huì)出現(xiàn)OOM,即便沒(méi)有出現(xiàn),大量的線程回收也會(huì)個(gè)GC帶來(lái)很大的壓力。

      可想而知,雖然多線程技術(shù)可以充分發(fā)揮多核處理器的計(jì)算能力,提高生產(chǎn)系統(tǒng)的吞吐量和性能。但是,若不加控制和管理的隨意使用線程,對(duì)系統(tǒng)的性能反而會(huì)產(chǎn)生不利的影響。

      還拿上邊的例子說(shuō),如果我們使用線程池的方式的話,可以實(shí)現(xiàn)最多創(chuàng)建愛(ài)你線程的數(shù)量,這樣的話就算再多的數(shù)據(jù)需要入庫(kù),只需要排隊(duì)等待線程池的線程即可,就不會(huì)出現(xiàn)線程池過(guò)多而消耗系統(tǒng)資源的情況,當(dāng)然這只是意見(jiàn)簡(jiǎn)單的場(chǎng)景。

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      說(shuō)到這里,有人要說(shuō)了線程不是攜帶資源的最小單位,操作系統(tǒng)的書籍中還給我們說(shuō)了線程之間的切換消耗很小嗎?雖然如此,線程是一種輕量級(jí)的工具(或者稱之為:輕量級(jí)進(jìn)程),但其創(chuàng)建和關(guān)閉依然需要花費(fèi)時(shí)間,如果為了一個(gè)很簡(jiǎn)單的任務(wù)就去創(chuàng)建一個(gè)線程,很有可能出現(xiàn)創(chuàng)建和銷毀線程所占用的時(shí)間大于該線程真實(shí)工作所消耗的時(shí)間,反而得不償失。

      那么什么是線程池?

      為了避免系統(tǒng)頻繁的創(chuàng)建和銷毀線程,我們可以將創(chuàng)建的線程進(jìn)行復(fù)用。數(shù)據(jù)庫(kù)中的數(shù)據(jù)庫(kù)連接池也是此意。

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      在線程池中總有那么幾個(gè)活躍的線程,也有一定的最大值限制,一個(gè)業(yè)務(wù)使用完線程之后,不是立即銷毀而是將其放入到線程池中,從而實(shí)現(xiàn)線程的復(fù)用。簡(jiǎn)而言之:創(chuàng)建線程變成了從線程池獲取空閑的線程,關(guān)閉線程變成了向池子中歸還線程。

      再多的概念,不過(guò)多解釋,因?yàn)楹芑A(chǔ),也不是本文的重點(diǎn)。

      JDK對(duì)線程池的支持

      JDK提供的Eexecutor框架

      JDK提供了Executor框架,可以讓我們有效的管理和控制我們的線程,其實(shí)質(zhì)也就是一個(gè)線程池。Executor下的接口和類繼承關(guān)系如下:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      其中,ExecutorService接口定義如下:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      如果使用Executor框架的話,Executors類是常用的,其方法如下:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      其中常用幾類如下:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      1、newFixedThreadPool:該方法返回一個(gè)固定線程數(shù)量的線程池;

      2、newSingleThreadExecutor:該方法返回一個(gè)只有一個(gè)現(xiàn)成的線程池;

      3、newCachedThreadPool:返回一個(gè)可以根據(jù)實(shí)際情況調(diào)整線程數(shù)量的線程池;

      4、newSingleThreadScheduledExecutor:該方法和newSingleThreadExecutor的區(qū)別是給定了時(shí)間執(zhí)行某任務(wù)的功能,可以進(jìn)行定時(shí)執(zhí)行等;

      5、newScheduledThreadPool:在4的基礎(chǔ)上可以指定線程數(shù)量。

      創(chuàng)建線程池是指調(diào)用的還是ThreadPoolExecutor

      在Executors類中,我們拿出來(lái)一個(gè)方法簡(jiǎn)單分析一下:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      可以看出,類似的其他方法一樣,在Executors內(nèi)部創(chuàng)建線程池的時(shí)候,實(shí)際創(chuàng)建的都是一個(gè)ThreadPoolExecutor對(duì)象,只是對(duì)ThreadPoolExecutor構(gòu)造方法,進(jìn)行了默認(rèn)值的設(shè)定。ThreadPoolExecutor的構(gòu)造方法如下:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      參數(shù)含義如下:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      Eexecutor框架實(shí)例

      1、實(shí)例一:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      submit(Runnable task)方法提交一個(gè)線程。

      但是使用最新的“阿里巴巴編碼規(guī)范插件”檢測(cè)一下會(huì)發(fā)現(xiàn):

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      阿里巴巴編碼規(guī)范插件地址:https://github.com/alibaba/p3c

      2、實(shí)例二:

      遵循阿里巴巴編碼規(guī)范的提示,示例如下:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      或者這樣:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      3、實(shí)例三:

      自定義ThreadFactory、自定義線程拒絕策略

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      更多實(shí)例代碼,可參考:

      https:///xuliugen/codes/ta5dbsge0kvhy62qu8li157

      使用submit的坑

      首先看一下實(shí)例:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      運(yùn)行結(jié)果:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      上述代碼,可以看出運(yùn)行結(jié)果為4個(gè),因該是有5個(gè)的,但是當(dāng)i=0的時(shí)候,100/0是會(huì)報(bào)錯(cuò)的,但是日志信息中沒(méi)有任何信息,是為什么那?如果使用了submit(Runnable task) 就會(huì)出現(xiàn)這種情況,任何的錯(cuò)誤信息都出現(xiàn)不了!

      這是因?yàn)槭褂胹ubmit(Runnable task) 的時(shí)候,錯(cuò)誤的堆棧信息跑出來(lái)的時(shí)候會(huì)被內(nèi)部捕獲到,所以打印不出來(lái)具體的信息讓我們查看,解決的方法有如下兩種:

      1、使用execute()代替submit();

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      運(yùn)行結(jié)果:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      2、使用Future

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

      運(yùn)行結(jié)果:

      Java多線程編程-(9)-使用線程池實(shí)現(xiàn)線程的復(fù)用和一些坑的避免

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多