上善若水,不进则退

姚毛毛的博客

左手代码,右手写诗

孔乙己:跟我学做菜……不,多线程吧!

孔乙己一到店,所有上机的人便都看着他笑,有的叫道,“孔乙己,你的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、数据库的性能调优,有……

有技术,有情怀,有温度

欢迎关注我:姚毛毛& 妖生

公众号

posted @ 2019-12-09 09:49  姚毛毛  阅读(...)  评论(...编辑  收藏