线程池 - 还可以这么理解?

关注公众号【1024个为什么】,及时接收最新推送文章!   

本文内容:
1、为什么面试官总爱问底层原理?
2、为什么看了很多遍,却还是记不住?
3、为什么去了趟银行就理解线程池了?

为什么面试官总爱问底层原理?

别的面试官都在问

我相信有一部分面试官有这样的想法,只不过是占少数而已。他们会在网上找一些面试题,自己大概研究一下(有的自己也稀里糊涂),就拿来考核应聘者。如果只是聊基本的使用,不拿底层原理为难为难你,不仅显得自己的技术水平一般,也彰显不出公司的技术实力。

确实能区分出不同层次的程序员

那些经典的面试题,相信大家都耳熟能详,而线程池的底层实现可谓是经典中的经典。
但是在日常的业务开发中,很少会用到多线程,线程池就更少了。所以,知不知道底层原理,就可以看出你是不是对技术有一定的钻研精神,是不是一个有技术追求、对自己要求更高的程序员。
虽然大家都心知肚明:如果不是为了面试,老子才不看什么原理呢

懂得原理才有可能打造出高效可靠的服务

可能很多人不认同这一点,觉得装 X。
这一点我想着重说一下,曾经我也对此嗤之以鼻,感觉工作中又用不到,看了确实没什么用。后来服务真正出问题的时候,因不懂原理而无从下手,慢慢的才体会到底层原理的重要性。

•知道了底层实现,才能正确的使用

我们用的语言、框架、插件等等,都可以看做是别人发明的工具。我们没必要重复发明工具,只要用好这些工具,开发出预期的业务产品即可。
但前提是你要了解这些工具,才能用的得心应手。就像刀具为什么分那么多种类,有用来剁的、有用来切的、有用来雕刻的。你非要拿雕刻刀来切片(就好比非要和 Redis 的持久化较劲),也不是不可以,自己体会吧。

•可以快速定位、解决问题

举个例子:
老式的摆钟,经常走不准,不是快就是慢。如果不懂原理,就只能在偏差大的时候把指针拨回到正确的位置(就像有些线上问题,找不到原因,但重启就没问题了,就只能在出问题的时候重启服务)。
这肯定不是长久之策,我们要研究其原理,走的快的时候说明钟摆摆动的快,可以适当往下放一放,半径长了,摆动就慢了;反之亦然。
对应到我们的服务也是一个道理。

•学习前辈们的经验,少跳坑

了解底层原理,不仅仅是为了排查问题(能遇到底层的问题也是看缘分的),更重要的是吸收它们的通用解决方案。很多线程级别的问题解决思路,放大到服务级别也同样适用。
我们都知道线程池有任务队列,放大到服务级别,我们用消息队列来解决服务节点收到的大量请求是一个道理。

为什么看了很多遍,却还是记不住?

还是看的少

我们大都是普通人,没有过目不忘的能力。记得高中英语老师说过,记忆的秘诀就是“重复”。

用得少

如果让你用 switch ... case 实现一段判断逻辑,是不是要思考一段时间;
但如果让你用 if ... else 来实现,可能就不假思索的写出来了,因为我们天天用、天天写,都快形成肌肉记忆了。

方法不对

有些确实不常用的,想长久不忘也不现实。理工科的很多知识都不用死记硬背的,学会推理,就不必担心记不住了。虽说记忆没什么诀窍,但前提是要理解了,难以理解的就想办法和自己身边的事物联系起来,形成关联记忆。从能记住的简单知识点,一步一步推理,浮现出复杂的知识点。

扯了这么多有的没的,都是大道理,空理论。还是要啰嗦一句,理论指导实践,想想马克思为什么这么伟大,这句话就不难理解了。

为什么去了趟银行就理解线程池了?

先设定一个场景,某银行网点,今天15:00 发售某个理财产品,收益 6%(收益诱人,购买的人估计要排队了)。

早上刚开门是这个样子的

还没有人来办理业务(绝大多数业务都可以在线上办理了,我上一次去银行还是身份证到期,需要去网点重新认证),总共 4 个窗口,只开了 2 个,休息区有 8 个座椅,等待着客户的到来。

对比线程池:
刚初始化好,核心线程数=2,最大线程数=4,线程工厂产生的线程名前缀都是“理财-00”,队列可放 8 个任务, 拒绝策略、非核心线程存活时间 后面会提到。

不一会,来了 2 个办理理财赎回业务的

取号后(如果中途补充材料,再次进入无需重新取号),两个窗口正好为这 2 人服务。

对比线程池:
有任务进来了,取号就相当于可重入锁,2 个核心线程被占用,未达到最大线程数队列是空的。

由于人一直不多,两个窗口一直忙忙碌碌,但也能应付的了。

快到15:00

一下来了 3 个人,大堂经理会说:窗口都在忙,拿个号先在休息区等一会儿吧。银行不会因为少量的客户等待而新开服务窗口

对比线程池:
又有任务进来了,2 个核心线程被占用,队列未满,先去排队,队列里有3个任务。原则就是不能刚有任务堆积,就新起线程。

15:00

这次一下又来了 5 个人,大堂经理还是安排客户在休息区等候,休息区已坐满。

对比线程池:
又有任务进来了,2 个核心线程被占用,队列未满,继续排队,队列里增加到了8个任务,队列已满。

此时,来了一个 VIP 客户

大堂经理一看休息区都坐满了,再不开新窗口办理业务,VIP 估计要投诉了。于是就协调新开一个窗口给VIP办理业务。休息区的客户表示不服啊,凭什么他插队?不服也不行,世界就是这么不公平。

对比线程池:
又有任务进来了,2 个核心线程被占用,尚未达到最大线程数,新起了 1 个非核心线程,新任务利用可重入锁的非公平特征直接抢到了非核心线程,队列仍然满位,一朝排队,永久排队。

又来一个 VIP 客户

还有一个窗口没有开放,大堂经理只好又协调新开一个窗口办理业务。

对比线程池:
又有任务进来了,2 个核心线程被占用,尚未达到最大线程数,又新起了 1 个非核心线程,被新来的任务抢到了,队列仍然满位,此时已达到最大线程数。

仍然有买理财的客户过来

大堂经理看了一下剩余的理财额度,正好能被排队的人买完。于是就告知客户,理财已售完,下次再来吧。

对比线程池:
又有任务进来了,2 个核心线程被占用,2 个非核心线程被占用,达到了最大线程数,队列里任务已满,触发了拒绝策略。如果自己实现拒绝策略,需要明确的告诉任务拒绝的原因,方便定位问题。如果不直接拒绝,也可以把任务引导到其他地方执行,比如 MQ。具体实现视业务场景而定。

终于办理完所有客户的业务了

对比线程池:
没有新任务进来,2 个核心线程空闲中,2 个非核心线程空闲中,队列为空

16:30

快下班了,应该不会有太多人来了。大堂经理对1、4 号窗口的说:再等5分钟,人不多的话,就关闭窗口,暂停服务。

对比线程池:
没有新任务进来,2 个核心线程空闲中,2 个非核心线程等了5分钟(非核心线程存活时长、时间单位)后发现没有新的任务需要执行,自行销毁,队列为空

还有几点没提到的

1.窗口在不知道是否还有人等待办理业务时,会一直按叫号器的下一个,直到没有。类似于线程池阻塞的去取任务;2.每个线程都是有状态的,类似于窗口上屏幕展示的“xxx 号正在办理业务”;3.线程池有自己的计数器,可以清楚的知道处理过多少任务,当前有队列多少任务等等,这些数据银行也有记录,在取号机都可以得到。

总结

1.底层原理确实重要;2.线程池的几大核心要素,上面的例子基本都涵盖了;3.线程池考虑到的问题及解决方案,服务节点也要考虑,也要给出服务级别的解决方案;4.生活中问题的解决方案,在开发中同样适用;

比如,我有几套房子要出租,自己又没有时间和精力去和租户对接,干脆就交给中介吧,专业的人做专业的事。这就好比我们的注册中心,服务的提供方和调用方不用一对一对接,加个中间层,交给注册中心去处理。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值