本文原文链接
尼恩说在前面
在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题:
如何确定系统的最佳线程数?
5000qps,下游一个接口响应时间 500ms,接口超时时间 1S,一台机器4核8g,如何设计线程池的核心线程数、最大线程数、队列,需要多少台机器
5000qps访问 一个 500ms响应时间接口,如何设计线程池的核心线程数、最大线程数? 需要多少台机器?
最近有小伙伴在面试阿里,又遇到了相关的面试题。小伙伴懵了,因为没有遇到过,所以支支吾吾的说了几句,面试官不满意,面试挂了。
所以,尼恩给大家做一下系统化、体系化的梳理,使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。
当然,这道面试题,以及参考答案,也会收入咱们的 《尼恩Java面试宝典PDF》V171版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。
最新《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请关注本公众号【技术自由圈】获取,回复:领电子书
本文目录
本文的配套视频, 尼恩的参考答应
详见链接:https://mp.weixin.qq.com/s/JFWjDSQ4HRGbZhj9ei3t6Q
线程使用的两个核心规范
首先看编程规范中, 有两个很重要的,与线程有关的需要强制执行的规范:
规范一:【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
说明:Java线程的创建非常昂贵,需要JVM和OS(操作系统)配合完成大量的工作:
1)消耗内存资源:必须为线程堆栈分配和初始化大量内存块,其中包含至少1MB的栈内存。
2)消耗CPU资源:需要进行系统调用,以便在OS(操作系统)中创建和注册内核线程,大量内核线程调度会导致CPU上下文过度切换。
所以,Java高并发应用频繁创建和销毁线程的操作将是非常低效的,而且是不被编程规范所允许的。
如何降低Java线程的创建成本?必须使用到线程池。使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。
以上的内容,在尼恩的 《Java 高并发核心编程 卷2》 进行了详细介绍。
规范二:【强制】 线程池不允许使用Executors去创建快捷线程池 ,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors返回的线程池对象的弊端如下:
- FixedThreadPool和SingleThreadPool: 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。
- CachedThreadPool和ScheduledThreadPool: 允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。
通过以上规范,说明我们应用中,需要用自定义线程池。然而,由于构造一个线程池竟然有7个参数