孔乙己:跟我學做菜……不,多線程吧!


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

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

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

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

“什么清白?我前兩天親眼見你翻了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這三個單詞。

孔乙己寫完得意地笑了,像極了那晚翻牆到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異步線程注解”,瘸着腿,一高一低的,漸漸地走遠了。

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

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

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

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

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


文章首發公眾號:姚毛毛的博客

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

有技術,有情懷,有溫度

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

公眾號


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM