孔乙己一到店,所有上機的人便都看着他笑,有的叫道,“孔乙己,你的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、數據庫的性能調優,有……
有技術,有情懷,有溫度
歡迎關注我:姚毛毛& 妖生