【原创】腾讯面试官:线程池要设置多大

【原创】腾讯面试官:线程池要设置多大

含泪播种的人一定能含笑收获。

有个朋友Hunter跟我聊,最近他参加腾讯的面试,在二面的时候被问到了关于线程池线程数目设置的一个问题。此处记录下这个问题的面试过程,以及后面关于此问题的理论方面的知识讲解。

面试过程

面试官开场了:

线程池你用过吧,线程数是怎么设置的呢?

Hunter心想,这不难啊,曾经在《Java并发编程》一书中有看到过线程池中线程数目设置的讲述,于是张口就来:

线程数的设置需要考虑三方面的因素,服务器的配置、服务器资源的预算和任务自身的特性。具体来说就是服务器有多少个CPU,多少内存,IO支持的最大QPS是多少,任务主要执行的是计算、IO还是一些混合操作,任务中是否包含数据库连接等的稀缺资源。线程池的线程数设置主要取决于这些因素。

面试官追问来了:

那具体是怎么设置呢?

Hunter略一思忖,整理了下思路,娓娓道来:

假设机器有N个CPU,那么对于计算密集型的任务,应该设置线程数为N+1;对于IO密集型的任务,应该设置线程数为2N;对于同时有计算工作和IO工作的任务,应该考虑使用两个线程池,一个处理计算任务,一个处理IO任务,分别对两个线程池按照计算密集型和IO密集型来设置线程数。

面试官表情毫无变化,接着发问:

N+1和2N是怎么来的?

Hunter张口就来:

是个经验值。

面试官:

经验值吗?那为什么不是N+2或者N+3,而非得是N+1呢?

Hunter被驳得稍有点懵,脑子里努力在回想学习过的那些技术点,竟一时语塞。

看得出来面试官略有不满,于是提示道:

那假如在一个请求中,计算操作需要5ms,DB操作需要100ms,对于一台8个CPU的服务器,怎么设置线程数呢?

Hunter努力平复心情,紧接着最开始的思路,说到:

这是一个计算和IO混合型的任务,可以将其分解为两个线程池来处理。一个线程池处理计算操作,设置N+1=9个线程,一个线程处理IO操作,设置2N=16个线程。

面试官:

如果一个任务同时包含了一个计算操作和DB操作呢,不能拆分怎么设置?你能讲一下具体的计算过程吗?

Hunter略有点慌,心里不断给自己暗示:这个问题不难不难。然后不断回想看过的《Java并发编程实战》和《Java虚拟机并发编程》中关于线程池设置的章节,并试图将自己对这个问题的分析思路也表达出来。

首先这个任务整体上是一个IO密集型的任务。在处理一个请求的过程中,总共耗时100+5=105ms,而其中只有5ms是用于计算操作的,CPU利用率为5/(100+5)。使用线程池是为了尽量提高CPU的利用率,减少对CPU资源的浪费,假设以100%的CPU利用率来说,要达到100%的CPU利用率,对于一个CPU就要设置其利用率的倒数个数的线程数,也即1/(5/(100+5)),8个CPU的话就乘以8。那么算下来的话,就是……168,对,这个线程池要设置168个线程数。

面试官表情略有缓和,嘴角微微一笑:

如果实际的任务差异较大,不同任务实际的CPU操作耗时和IO操作耗时有所不同,那么怎么设置线程数呢?

经过刚才的分析过程,Hunter心里已经回忆起了这块的知识点,已然不慌了。

那对所有任务的CPU操作耗时和IO操作耗时求个平均值就好了。

Hunter心里渐渐恢复了自信,大脑的利用率瞬间提高好几十个百分点。

面试官轻轻“嗯”了一声,表示认可。

那如果现在这个IO操作是DB操作,而DB的QPS上限是1000,这个线程池又该设置为多大呢?

经过刚才的心理调整,对问题完整的分析过程,以及面试官的略微认可,Hunter已经知道如何去更好地回答面试官的问题了。

按比例来减少就可以了,按照之前的计算过程,可以计算出来当线程数设置为168的时候,DB操作的QPS为,168(1000/(100+5))=1600,如果现在DB的QPS最大为1000,那么对应的,最大只能设置168(1000/1600)=105个线程。

面试官这次是真的满意了,给这个回答给了一个正面的评价:

思路挺清晰的。那设置线程池的时候除了考虑这些,还需要考虑哪些内容呢?

Hunter此时已经完全找回自信了,不惧任何问题。

除了考虑任务CPU操作耗时、IO操作耗时之外,还需要服务器的内存资源、硬盘资源、网络带宽等等的。

面试官点点头,看起来Hunter已经获得了面试官的正式认可了。面试官告诉Hunter,表现不错,等接下来的面试安排吧。

面试后总结

Hunter内心异常激动,这真算是一次“死里逃生”的经历了。面试结束后,Hunter压抑兴奋,马上去找到《Java并发编程实战》和《Java虚拟机并发编程》两本书,翻到对应的章节,想确认下自己的回答。
果然,压力除了会造成紧张之外,也能提高大脑利用率。Hunter在调整状态后的回答完全正确。附上两本书中对线程池设置的理论。

线程数的第一种计算方法

在《Java并发编程实践》中,是这样来计算线程池的线程数目的:

在一个基准负载下,使用 几种不同大小的线程池运行你的应用程序,并观察CPU利用率的水平。
给定下列定义:
Ncpu = CPU的数量
Ucpu = 目标CPU的使用率, 0 <= Ucpu <= 1
W/C = 等待时间与计算时间的比率
为保持处理器达到期望的使用率,最优的池的大小等于:
  Nthreads = Ncpu x Ucpu x (1 + W/C)

这种计算方式,我们需要知道上面定义的几个数值,才能计算出来线程池需要设置的线程数。其中,CPU数量是确定的,CPU使用率是目标值也是确定的,W/C也是可以通过基准程序测试得出的。

线程数的第二种计算方法

而在《Java虚拟机并发编程》中,则是这样来计算线程池的线程数目的:

线程数 = CPU可用核心数/(1 - 阻塞系数),其中阻塞系数的取值在0和1之间。
计算密集型任务的阻塞系数为0,而IO密集型任务的阻塞系数则接近1。一个完全阻塞的任务是注定要挂掉的,所以我们无须担心阻塞系数会达到1。

这种计算方式,我们需要知道CPU可用核心数和阻塞系数,才能计算出来线程池需要设置的线程数目。其中,CPU可用核心数是确定的,阻塞系数可以通过公式:阻塞系数=阻塞时间/(阻塞时间+计算时间),其实也就是上一种算法中的W/C的方式来计算,所以阻塞系数也是可以通过基准程序计算得出的。

所谓的经验值怎么来的

那么我们再来看所谓的N+1与2N的经验值的来源。
计算密集型应用
以第一种计算方式来看,对于计算密集型应用,假定等待时间趋近于0,是的CPU利用率达到100%,那么线程数就是CPU核心数,那这个+1意义何在呢?
《Java并发编程实践》这么说:

计算密集型的线程恰好在某时因为发生一个页错误或者因其他原因而暂停,刚好有一个“额外”的线程,可以确保在这种情况下CPU周期不会中断工作。

所以N+1确实是一个经验值。
IO密集型应用
同样以第一种方式来看,对于IO密集型应用,假定所有的操作时间几乎都是IO操作耗时,那么W/C的值就为1,那么对应的线程数确实为2N。

本文由微型公众号【Dali王的技术博客】原创,扫码关注获取更多原创技术文章。


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容