Java線程池的四種用法與使用場景

一婆硬、如下方式存在的問題

new Thread() {    @Override    public void run() {        // 業(yè)務邏輯    }}.start();

1、首先頻繁的創(chuàng)建彬犯、銷毀對象是一個很消耗性能的事情;2湖蜕、如果用戶量比較大宋列,導致占用過多的資源,可能會導致我們的服務由于資源不足而宕機灭返;3坤邪、綜上所述,在實際的開發(fā)中罩扇,這種操作其實是不可取的一種方式怕磨。

二消约、使用線程池有什么優(yōu)點

1员帮、線程池中線程的使用率提升,減少對象的創(chuàng)建氯材、銷毀硝岗;2、線程池可以控制線程數(shù)冗尤,有效的提升服務器的使用資源仓坞,避免由于資源不足而發(fā)生宕機等問題嫉称;

三蒲稳、線程池的四種使用方式

1、newCachedThreadPool

創(chuàng)建一個線程池晾腔,如果線程池中的線程數(shù)量過大剔应,它可以有效的回收多余的線程纤控,如果線程數(shù)不足惜辑,那么它可以創(chuàng)建新的線程抵卫。

public static void method() throws Exception {    ExecutorService executor = Executors.newCachedThreadPool();    for (int i = 0; i < 5; i++) {        final int index = i;        Thread.sleep(1000);        executor.execute(new Runnable() {            @Override            public void run() {                System.out.println(Thread.currentThread().getName() + "  " + index);            }        });    }}

執(zhí)行結(jié)果

1

通過分析我看可以看到婚瓜,至始至終都由一個線程執(zhí)行蛉签,實現(xiàn)了線程的復用,并沒有創(chuàng)建多余的線程锻全。如果當我們的業(yè)務需要一定的時間進行處理,那么將會出現(xiàn)什么結(jié)果泪漂。我們來模擬一下歪泳。
2

可以明顯的看出,現(xiàn)在就需要幾條線程來交替執(zhí)行敌卓。

不足:這種方式雖然可以根據(jù)業(yè)務場景自動的擴展線程數(shù)來處理我們的業(yè)務伶氢,但是最多需要多少個線程同時處理缺是我們無法控制的;

優(yōu)點:如果當?shù)诙€任務開始癣防,第一個任務已經(jīng)執(zhí)行結(jié)束,那么第二個任務會復用第一個任務創(chuàng)建的線程幕屹,并不會重新創(chuàng)建新的線程级遭,提高了線程的復用率;

2装畅、newFixedThreadPool

這種方式可以指定線程池中的線程數(shù)掠兄。舉個栗子锌雀,如果一間澡堂子最大只能容納20個人同時洗澡迅诬,那么后面來的人只能在外面排隊等待。如果硬往里沖侈贷,那么只會出現(xiàn)一種情景,摩擦摩擦...

首先測試一下最大容量為一個線程撑蚌,那么會不會是我們預測的結(jié)果搏屑。

public static void method_01() throws InterruptedException {    ExecutorService executor = Executors.newFixedThreadPool(1);    for (int i = 0; i < 10; i++) {        Thread.sleep(1000);        final int index = i;        executor.execute(() -> {            try {                Thread.sleep(2 * 1000);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println(Thread.currentThread().getName() + "  " + index);        });    }    executor.shutdown();}

執(zhí)行結(jié)果

3

我們改為3條線程再來看下結(jié)果

4

優(yōu)點:兩個結(jié)果綜合說明辣恋,newFixedThreadPool的線程數(shù)是可以進行控制的,因此我們可以通過控制最大線程來使我們的服務器打到最大的使用率伟骨,同事又可以保證及時流量突然增大也不會占用服務器過多的資源。

3继蜡、newScheduledThreadPool

該線程池支持定時暑中,以及周期性的任務執(zhí)行,我們可以延遲任務的執(zhí)行時間鳄逾,也可以設置一個周期性的時間讓任務重復執(zhí)行。 該線程池中有以下兩種延遲的方法殴俱。

  • scheduleAtFixedRate

測試一

public static void method_02() {    ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);    executor.scheduleAtFixedRate(new Runnable() {        @Override        public void run() {            long start = new Date().getTime();            System.out.println("scheduleAtFixedRate 開始執(zhí)行時間:" +                    DateFormat.getTimeInstance().format(new Date()));            try {                Thread.sleep(5000);            } catch (InterruptedException e) {                e.printStackTrace();            }            long end = new Date().getTime();            System.out.println("scheduleAtFixedRate 執(zhí)行花費時間=" + (end - start) / 1000 + "m");            System.out.println("scheduleAtFixedRate 執(zhí)行完成時間:" + DateFormat.getTimeInstance().format(new Date()));            System.out.println("======================================");        }    }, 1, 5, TimeUnit.SECONDS);}

執(zhí)行結(jié)果

5

測試二

6

總結(jié):以上兩種方式不同的地方是任務的執(zhí)行時間线欲,如果間隔時間大于任務的執(zhí)行時間汽摹,任務不受執(zhí)行時間的影響。如果間隔時間小于任務的執(zhí)行時間趴泌,那么任務執(zhí)行結(jié)束之后,會立馬執(zhí)行嗜憔,至此間隔時間就會被打亂。

  • scheduleWithFixedDelay

測試一

public static void method_03() {    ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);    executor.scheduleWithFixedDelay(new Runnable() {        @Override        public void run() {            long start = new Date().getTime();            System.out.println("scheduleWithFixedDelay 開始執(zhí)行時間:" +                    DateFormat.getTimeInstance().format(new Date()));            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }            long end = new Date().getTime();            System.out.println("scheduleWithFixedDelay執(zhí)行花費時間=" + (end - start) / 1000 + "m");            System.out.println("scheduleWithFixedDelay執(zhí)行完成時間:"                    + DateFormat.getTimeInstance().format(new Date()));            System.out.println("======================================");        }    }, 1, 2, TimeUnit.SECONDS);}

執(zhí)行結(jié)果

7

測試二

public static void method_03() {    ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);    executor.scheduleWithFixedDelay(new Runnable() {        @Override        public void run() {            long start = new Date().getTime();            System.out.println("scheduleWithFixedDelay 開始執(zhí)行時間:" +                    DateFormat.getTimeInstance().format(new Date()));            try {                Thread.sleep(5000);            } catch (InterruptedException e) {                e.printStackTrace();            }            long end = new Date().getTime();            System.out.println("scheduleWithFixedDelay執(zhí)行花費時間=" + (end - start) / 1000 + "m");            System.out.println("scheduleWithFixedDelay執(zhí)行完成時間:"                    + DateFormat.getTimeInstance().format(new Date()));            System.out.println("======================================");        }    }, 1, 2, TimeUnit.SECONDS);}

執(zhí)行結(jié)果

8

總結(jié):同樣的,跟scheduleWithFixedDelay測試方法一樣币励,可以測出scheduleWithFixedDelay的間隔時間不會受任務執(zhí)行時間長短的影響滋早。

4、newSingleThreadExecutor

這是一個單線程池杆麸,至始至終都由一個線程來執(zhí)行浪感。

public static void method_04() {    ExecutorService executor = Executors.newSingleThreadExecutor();    for (int i = 0; i < 5; i++) {        final int index = i;        executor.execute(() -> {            try {                Thread.sleep(2 * 1000);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println(Thread.currentThread().getName() + "   " + index);        });    }    executor.shutdown();}

執(zhí)行結(jié)果

9

四影兽、線程池的作用

線程池的作用主要是為了提升系統(tǒng)的性能以及使用率。文章剛開始就提到峻堰,如果我們使用最簡單的方式創(chuàng)建線程讹开,如果用戶量比較大捐名,那么就會產(chǎn)生很多創(chuàng)建和銷毀線程的動作,這會導致服務器在創(chuàng)建和銷毀線程上消耗的性能可能要比處理實際業(yè)務花費的時間和性能更多成艘。線程池就是為了解決這種這種問題而出現(xiàn)的贺归。

同樣思想的設計還有很多,比如數(shù)據(jù)庫連接池拂酣,由于頻繁的連接數(shù)據(jù)庫,然而創(chuàng)建連接是一個很消耗性能的事情剑勾,所有數(shù)據(jù)庫連接池就出現(xiàn)了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盯另,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子鸳惯,更是在濱河造成了極大的恐慌叠萍,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辅鲸,死亡現(xiàn)場離奇詭異腹殿,居然都是意外死亡,警方通過查閱死者的電腦和手機锣尉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門自沧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坟奥,“玉大人拇厢,你說我怎么就攤上這事》玫校” “怎么了邪媳?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長雨效。 經(jīng)常有香客問我,道長叮姑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任耘沼,我火速辦了婚禮朱盐,結(jié)果婚禮上群嗤,老公的妹妹穿的比我還像新娘兵琳。我一直安慰自己,他們只是感情好者春,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布清女。 她就那樣靜靜地躺著,像睡著了一般嫡丙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上稻扬,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天羊瘩,我揣著相機與錄音盼砍,去河邊找鬼。 笑死浇坐,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的擒贸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼介劫,長吁一口氣:“原來是場噩夢啊……” “哼案淋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起誉碴,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎黔帕,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呐芥,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡慨默,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了潮太。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虾攻。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖奇钞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情景埃,我是刑警寧澤顶别,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站完慧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏屈尼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一脾歧、第九天 我趴在偏房一處隱蔽的房頂上張望乞巧。 院中可真熱鬧,春花似錦、人聲如沸免猾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锨苏。三九已至,卻和暖如春伞租,著一層夾襖步出監(jiān)牢的瞬間限佩,已是汗流浹背葵诈。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工作喘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留晕城,地道東北人泞坦。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓贰锁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親李根。 傳聞我的和親對象是個殘疾皇子几睛,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355