1. 程式人生 > >孔乙己:跟我學做菜……不,多執行緒吧!

孔乙己:跟我學做菜……不,多執行緒吧!

孔乙己一到店,所有上機的人便都看著他笑,有的叫道,“孔乙己,你的github上又添star了”。

他不回答,對櫃裡說,“開個機子,再來個9塊9套餐。”便排出九行大錢。“現錢!”

他們又故意高聲的嚷道:“你一定又FQ了吧。”

孔乙己睜大眼睛說,“你怎麼這樣憑空汙人家清白……”

“什麼清白?我前兩天親眼見你翻了P站的牆,吊著打。”

孔乙己便漲紅了臉,額上的青筋條條綻出,爭辯道,“翻P站不能算翻……P站!……程式設計師兒的事,能算翻麼?”

接連便是難懂的話,什麼“P站學技術”,“G站交友”這類,引得眾人都鬨笑起來;店內外充滿了快活的空氣。

有一回他對我說道:“姚毛毛,你寫過程式麼?”

我略略一點頭。

他說,“寫過程式……我便考一考你。多執行緒怎麼建立的?”

我想,討飯一樣的人,也配考我麼?便回過臉去,不再理會。

孔乙己等了很久,很懇切的說道,“不能寫罷?……我教給你,記著!這些方法,將來做CTO的時候,寫程式碼要用。”

我暗想我和CTO的等級還很遠呢,而且我們CTO從來不寫程式碼;又好笑,又不耐煩,懶懶的答他道,“誰要你教,不就是new Thread麼?”

孔乙己顯出極高興的樣子,將兩個指頭敲著櫃檯,點頭說,“對呀對呀!……執行緒有5種建立方法,你知道麼?執行緒池你知道嗎?執行緒等待知道嗎?”

孔乙己剛用指頭敲了敲鍵盤,想在IDE中寫幾行程式碼,見我毫不熱心,便又嘆一口氣,顯出極惋惜的樣子。

我見他這模樣,就心生了幾分憐憫,應了一聲,“有5種方法啊,你說來聽聽。”

孔乙己立時精神一振,便把左右手兩個手指頭重新搭在了鍵盤上。

“lamada表示式知道吧?java8的新特性,用這種寫法賊爽。”孔乙己漲紅了臉,吐了口唾沫,“你看這樣 new Thread就行。”

說著,寫出下面這行程式碼。

new Thread(() -> {
    // do something
 }).start();
 

“這不就是new Runnable()的簡寫嘛。”我撇撇嘴,便寫給他看。

Thread thread =  new Thread(new Runnable() {
    @Override
    public void run() {
         // do something
    }
});

孔乙己搖了搖頭,“是耶?非耶?lamada的效率可比它高呢。”

“那還有三種呢?”我看著孔乙己滿足的神情,不忍心打破,便又順著他的話問下去。

“其他的三種分別是extends Thread、implements Runnable、implements Callable,Callable要跟FutureTask一起用,可以返回執行結果。”孔乙己粗短的手指便賣力的在鍵盤上敲了起來。

我已然不耐,沒有心思看他的程式碼,只想早早把他打發,便說道,“那怎麼做執行緒等待呢?真的有5種嗎?”

孔乙己“呵呵”的笑了兩聲,像是被捏住喉嚨的鴨子,“join你知道吧?還有門閂、柵欄、訊號量你聽過嗎?就是這樣寫的……”

說著,寫出CountDownLatch、CyclicBarrier、Semaphore這三個單詞。

孔乙己寫完得意地笑了,像極了那晚FQ到P站後的笑容。“後面這三個可是能線上程池執行中進行執行緒等待的。”

我疑惑道,“那還有一個呢”?

孔乙己愈發得意,“white true 加isTerminated 呀!”

 while (true) {
    if (threadPool.isTerminated()) {
        System.out.println("執行緒池關閉");
        break;
    }
    Thread.sleep(200);
}

嗨,學這麼多有啥用呢?我暗想,這像你,腿也瘸了,頭也禿了。只是我嘴上卻說道,“那麼,這執行緒池幾種寫法呢?”

孔乙己似乎拿起了架子。他摘下眼鏡,哈了口氣在上面,又擦了擦,才慢條斯理地說道,“主要就是兩種執行緒類呢!其他的都是繼承的。”

我隨口搭了一聲,“是ThreadPool跟ForkJoinPool麼?”

孔乙己蒼白的臉上泛起了不正常的紅暈,“對的,對的。”說著,立馬敲下了程式碼。

ExecutorService threadPool = null;

// 彈性快取執行緒池
threadPool = Executors.newCachedThreadPool();

// 固定大小執行緒池
threadPool = Executors.newFixedThreadPool(3);

// 定時任務執行緒池
threadPool = Executors.newScheduledThreadPool(2);

// 單執行緒的執行緒池,只有一個執行緒在工作
threadPool = Executors.newSingleThreadExecutor();

// ThreadPool 預設執行緒池,可控制引數比較多
threadPool = new ThreadPoolExecutor();

// ForkJoinPool 預設執行緒池,少量執行緒、大量IO操作時使用
ForkJoinPool threadPool = new ForkJoinPool(5);

// ForkJoinPool的一種
ExecutorService workStealingPool = Executors.newWorkStealingPool(5);

孔乙己“嘖嘖”嘴,“其實仔細算起來是七種執行緒池呢!”

接著便又嘀咕起了“四種拒絕策略”、“三種阻塞佇列”這些難懂的話。

我就這樣站在櫃上跟孔乙己聊了好些時候,掌櫃的也不來攔我,畢竟孔乙己也是能帶來快活空氣的人兒呢。

就在臨走的時候,孔乙己還說道,“你會用springboot吧?springboot裡還有兩種註解也可以建立多執行緒任務呢。”

我沒再理會他,但聽他說著“定時器@Scheduled註解”、“@Async非同步執行緒註解”,瘸著腿,一高一低的,漸漸地走遠了。

此後,便再也沒看到孔乙己了,也偶爾聽到來上機的客人說道,他是哪天FQ被人抓了,腿都給打折了。

到了年關,掌櫃的還說“孔乙己還欠十九個錢呢!”

到第二年的端午,又說“孔乙己還欠十九個錢呢!”

到中秋卻是沒說了,再到年關還是沒有見到他。

我到現在終於沒有見——大約孔乙己的確死了。


文章首發公眾號:姚毛毛的部落格

這裡有我的程式設計生涯感悟與總結,有Java、Linux、Oracle、mysql的相關技術,有工作中進行的架構設計實踐和讀書理論,有JVM、Linux、資料庫的效能調優,有……

有技術,有情懷,有溫度

歡迎關注我:姚毛毛& 妖生