Java---線程池

什么是線程池

官方文檔描述

An {@link ExecutorService} that executes each submitted task using one of possibly 
several pooled threads, normally configured using {@link Executors} factory methods.

大體意思是ExecutorService借助池中線程來(lái)處理每一個(gè)提交的任務(wù),通常使用Executors的工廠方法來(lái)配置線程池该溯。

為什么要用線程池

線程池解決了兩個(gè)問題:

  • 執(zhí)行大量的異步任務(wù)時(shí),使用線程池減少每個(gè)任務(wù)的調(diào)用開銷啡专,提高性能

執(zhí)行一個(gè)線程任務(wù)的流程:創(chuàng)建線程磕潮、執(zhí)行線程中的任務(wù)石窑、銷毀線程播歼。當(dāng)執(zhí)行大量的異步任務(wù)時(shí)伶跷,頻繁的創(chuàng)建和銷毀線程的時(shí)間占據(jù)大部分比例掰读,使用線程池技術(shù)維護(hù)核心和最大的線程池?cái)?shù)來(lái)避免頻繁的創(chuàng)建和銷毀線程所占據(jù)的時(shí)間秘狞,提高性能。

  • 執(zhí)行任務(wù)集合時(shí)蹈集,線程池提供一種限制和管理資源的方案

執(zhí)行任務(wù)集合時(shí)烁试,由于處理器單元是有限的,線程池技術(shù)提供核心線程池拢肆、最大線程池限制線程可同時(shí)運(yùn)行的線程個(gè)數(shù)减响,減少處理器單元的閑置時(shí)間,增加處理器單元的吞吐能力郭怪。

ThreadPoolExecutor支示、AbstractExecutorService、ExecutorService鄙才、Executor之間的關(guān)系

通過(guò)下面代碼可以很清楚了解到他們之間的關(guān)系颂鸿,圖我就不花了。攒庵。嘴纺。

public class ThreadPoolExecutor extends AbstractExecutorService 
public abstract class AbstractExecutorService implements ExecutorService
public interface ExecutorService extends Executor {
    void shutdown();    // 關(guān)閉所有任務(wù)
    List<Runnable> shutdownNow();   // 立即關(guān)閉所有任務(wù)
    boolean isShutdown();       // 是否被關(guān)閉
    boolean isTerminated();     // 是否被終止運(yùn)行
    Future<?> submit(Runnable task);    // 提交任務(wù)到線程池中運(yùn)行,最后還是交于execute方法執(zhí)行
    ....
}
public interface Executor {
    void execute(Runnable command); // 執(zhí)行任務(wù)
}

ThreadPoolExecutor類構(gòu)造函數(shù)參數(shù)分析

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        ....                              
    }
  • corePoolSize:保持在線程池中的線程線程數(shù)浓冒,除非調(diào)用allowCoreThreadTimeOut方法栽渴,否則該線程閑置也不會(huì)被銷毀
  • maximumPoolSize:線程池中允許創(chuàng)建的最大線程數(shù)(包含核心線程池)
  • keepAliveTime:當(dāng)線程池中線程創(chuàng)建數(shù)大于核心線程數(shù),沒有新任務(wù)可以被處理而閑置keepAliveTime時(shí)間時(shí)自動(dòng)銷毀該類型線程
  • unit:keepAliveTime的時(shí)間單位
  • workQueue:工作隊(duì)列稳懒,這個(gè)隊(duì)列將維持被執(zhí)行的任務(wù)
  • threadFactory:線程工程闲擦,用于創(chuàng)建新的線程
  • handler:當(dāng)線程任務(wù)被拒時(shí)的處理者

線程池使用demo

下面例子是線程池的簡(jiǎn)單用法,不具備代表性场梆。但是墅冷,確是比較有意思的一個(gè)例子,Callable和Future搭配可以實(shí)現(xiàn)等待多個(gè)任務(wù)完成后統(tǒng)一處理辙谜。有一些很雞肋的場(chǎng)景俺榆,例如通過(guò)多個(gè)接口獲取主頁(yè)不同類型數(shù)據(jù)后刷新界面,哎装哆,主要是服務(wù)端寫成了多個(gè)接口罐脊,我也是很無(wú)奈╮(╯▽╰)╭定嗓。

import java.util.concurrent.*;

public class Main {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                Thread.sleep(1000);
                return "callable sleep 1s";
            }
        };
        Callable<String> callable1 = new Callable<String>() {
            @Override
            public String call() throws Exception {
                Thread.sleep(2000);
                return "callable sleep 2s";
            }
        };
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("I'm runnable. I'm finished.");
            }
        });
        Future<String> submit = executorService.submit(callable);
        Future<String> submit1 = executorService.submit(callable1);
        String s = submit.get();
        String s1 = submit1.get();
        System.out.println("callable resule: s=>" + s + "  s1=>" + s1);
    }
}

輸出:
I'm runnable. I'm finished.
callable resule: s=>callable sleep 1s  s1=>callable sleep 2s

線程池鉤子方法

/**
 * <dt>Hook methods</dt>
 *
 * <dd>This class provides {@code protected} overridable
 * {@link #beforeExecute(Thread, Runnable)} and
 * {@link #afterExecute(Runnable, Throwable)} methods that are called
 * before and after execution of each task.  These can be used to
 * manipulate the execution environment; for example, reinitializing
 * ThreadLocals, gathering statistics, or adding log entries.
 */

主要的意思是系統(tǒng)提供兩個(gè)鉤子方法beforeExecuteafterExecute方法,他們分別是在任務(wù)執(zhí)行之前和執(zhí)行之后調(diào)用萍桌。用途宵溅,比如重新初始化線程變量收集靜態(tài)數(shù)據(jù)上炎、添加日志實(shí)體等恃逻。下面是官方的例子:

class PausableThreadPoolExecutor extends ThreadPoolExecutor {
   private boolean isPaused;
   private ReentrantLock pauseLock = new ReentrantLock();
   private Condition unpaused = pauseLock.newCondition();

   public PausableThreadPoolExecutor(...) { super(...); }

   protected void beforeExecute(Thread t, Runnable r) {
     super.beforeExecute(t, r);
     pauseLock.lock();
     try {
       while (isPaused) unpaused.await();
     } catch (InterruptedException ie) {
       t.interrupt();
     } finally {
       pauseLock.unlock();
     }
   }

   public void pause() {
     pauseLock.lock();
     try {
       isPaused = true;
     } finally {
       pauseLock.unlock();
     }
   }

   public void resume() {
     pauseLock.lock();
     try {
       isPaused = false;
       unpaused.signalAll();
     } finally {
       pauseLock.unlock();
     }
   }
}

本文對(duì)于線程池的講解比較淺顯,只要是講解線程池的基礎(chǔ)使用

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末藕施,一起剝皮案震驚了整個(gè)濱河市寇损,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌裳食,老刑警劉巖矛市,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異诲祸,居然都是意外死亡浊吏,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門救氯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)找田,“玉大人,你說(shuō)我怎么就攤上這事着憨《昭茫” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵享扔,是天一觀的道長(zhǎng)底桂。 經(jīng)常有香客問我,道長(zhǎng)惧眠,這世上最難降的妖魔是什么籽懦? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮氛魁,結(jié)果婚禮上暮顺,老公的妹妹穿的比我還像新娘。我一直安慰自己秀存,他們只是感情好捶码,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著或链,像睡著了一般惫恼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上澳盐,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天祈纯,我揣著相機(jī)與錄音令宿,去河邊找鬼。 笑死腕窥,一個(gè)胖子當(dāng)著我的面吹牛粒没,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播簇爆,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼癞松,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了入蛆?” 一聲冷哼從身側(cè)響起响蓉,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎安寺,沒想到半個(gè)月后厕妖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挑庶,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了软能。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迎捺。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖查排,靈堂內(nèi)的尸體忽然破棺而出凳枝,到底是詐尸還是另有隱情,我是刑警寧澤跋核,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布岖瑰,位于F島的核電站,受9級(jí)特大地震影響砂代,放射性物質(zhì)發(fā)生泄漏蹋订。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一刻伊、第九天 我趴在偏房一處隱蔽的房頂上張望露戒。 院中可真熱鬧,春花似錦捶箱、人聲如沸智什。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)荠锭。三九已至,卻和暖如春晨川,著一層夾襖步出監(jiān)牢的瞬間证九,已是汗流浹背键思。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留甫贯,地道東北人吼鳞。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像叫搁,于是被迫代替她去往敵國(guó)和親赔桌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 線程池是什么渴逻? 線程池用于多線程處理中疾党,它可以根據(jù)系統(tǒng)的情況,可以有效控制線程執(zhí)行的數(shù)量惨奕,優(yōu)化運(yùn)行效果雪位。線程池做的...
    懶癌正患者閱讀 2,743評(píng)論 2 80
  • 一.Java中的ThreadPoolExecutor類 java.uitl.concurrent.ThreadPo...
    誰(shuí)在烽煙彼岸閱讀 647評(píng)論 0 0
  • 更多 Java 并發(fā)編程方面的文章,請(qǐng)參見文集《Java 并發(fā)編程》 線程組 Thread Group 線程的集合...
    專職跑龍?zhí)?/span>閱讀 1,359評(píng)論 0 3
  • 我是近視眼梨撞,你知道吧雹洗!而且是資深老近視,其源頭可以追溯到青澀的初中階段卧波。這么多年以來(lái)我一直秉承“朦朧的世界更美好”...
    林雅閱讀 376評(píng)論 3 3
  • 第一次寫作不知道怎么開始时肿,周六下班走在路上忽然想起了老爹。印象中的老爹年輕的時(shí)候有點(diǎn)帥港粱,脾氣不好螃成,一言不和就來(lái)脾氣...
    品牌人Yama閱讀 279評(píng)論 0 0