一道面试题
兄弟们,怎么说?
我觉得如果你工作了两年左右的时间,或者是突击准备了面试,这题回答个八成上来,应该是手到擒来的事情。这题中规中矩,考点清晰,可以说的东西不是很多。
但是这都上血书了,那不得分析一波?
先把这个面试题拿出来一下:
1000 多个并发线程,10 台机器,每台机器 4 核,设计线程池大小。
这题给的信息非常的简陋,但是简陋的好处就是想象空间足够大。
第一眼看到这题的时候,我直观的感受到了两个考点:
- 线程池设计。
- 负载均衡策略。
我就开门见山的给你说了,这两个考点,刚好都在我之前的文章的射程范围之内:
《如何设置线程池参数?美团给出了一个让面试官虎躯一震的回答》
下面我会针对我感受到的这两个考点去进行分析。
线程池设计
我们先想简单一点:1000 个并发线程交给 10 台机器去处理,那么 1 台机器就是承担 100 个并发请求。
100 个并发请求而已,确实不多。
而且他也没有说是每 1 秒都有 1000 个并发线程过来,还是偶尔会有一次 1000 个并发线程过来。
先从线程池设计的角度去回答这个题。
要回答好这个题目,你必须有两个最基本的知识贮备:
- 自定义线程池的 7 个参数。
- JDK 线程池的执行流程。
先说第一个,自定义线程池的 7 个参数。
java.util.concurrent.ThreadPoolExecutor#ThreadPoolExecutor
害,这 7 个参数我真的都不想说了,你去翻翻历史文章,我都写过多少次了。你要是再说不出个头头是道的,你都对不起我写的这些文章。
而且这个类上的 javadoc 已经写的非常的明白了。这个 javadoc 是 Doug Lea 老爷子亲自写的,你都不拜读拜读?
为了防止你偷懒,我把老爷子写的粘下来,我们一句句的看。
关于这几个参数,我通过这篇文章再说最后一次。
如果以后的文章我要是再讲这几个参数,我就不叫 why 哥,以后你们就叫我小王吧。
写着写着,怎么还有一种生气的感觉呢。似乎突然明白了当年在讲台上越讲越生气的数学老师说的:这题我都讲了多少遍了!还有人错?
好了,不生气了,说参数:
- corePoolSize:the number of threads to keep in the pool, even if they are idle, unless {@code allowCoreThreadTimeOut} is set (核心线程数大小:不管它们创建以后是不是空闲的。线程池需要保持 corePoolSize 数量的线程,除非设置了 allowCoreThreadTimeOut。)
- maximumPoolSize:the maximum number of threads to allow in the pool。 (最大线程数:线程池中最多允许创建 maximumPoolSize 个线程。)
- keepAliveTime:when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating。 (存活时间:如果经过 keepAliveTime 时间后,超过核心线程数的线程还没有接受到新的任务,那就回收。)
- unit:the time unit for the {@code keepAliveTime} argument (keepAliveTime 的时间单位。)
- workQueue:the queue to use for holding tasks before they are executed. This queue will hold only the {@code Runnable} tasks submitted by the {@code execute} method。 (存放待执行任务的队列:当提交的任务数超过核心线程数大小后,再提交的任务就存放在这里。它仅仅用来存放被 execute 方法提交的 Runnable 任务。所以这里就不要翻译为工作队列了,好吗?不要自己给自己挖坑。)
- threadFactory:the factory to use when the executor creates a new thread。 (线程工程:用来创建线程工厂。比如这里面可以自定义线程名称,当进行虚拟机栈分析时,看着名字就知道这个线程是哪里来的,不会懵逼。)
- handler :the handler to use when execution is blocked because the thread bounds and queue capacities are reached。 (拒绝策略:当队列里面放满了任务、最大线程数的线程都在工作时,这时继续提交的任务线程池就处理不了,应该执行怎么样的拒绝策略。)
第一个知识贮备就讲完了,你先别开始背,这玩意你背下来有啥用,你得结合着执行流程去理解。
接下来我们看第二个:JDK 线程池的执行流程。
一图胜千言: