面试官:自定义线程池的最大线程数如何配置最好?

一、背景

上篇文章通过图文并茂结合生活中的例子的方式,讲解了线程池的原理,其中演示并说明了自定义线程池的7大参数,针对参数之一最大线程创建数该如何定义呢?

二、线程和CPU的关系

在搞懂线程与CPU的关系前,先思考一个问题:Java真的可以开启线程吗?

public synchronized void start() {
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
​
        // 将此线程加入线程组
        group.add(this);
​
        boolean started = false;
        try {
            // 执行start0方法,真正执行线程
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
            }
        }
}
​
// 本地方法,调用底层的c++
private native void start0();

通过Thread线程的start()启动方法可以得知,只是将当前线程加入到一个线程组中,真正开启线程的方法是start0(),并且是一个native本地方法,实际上是调用底层的C++,Java是无法操作硬件,它是运行在虚拟机之上的。

线程是CPU调度和分配的基本单位(即CPU只能看到线程)

线程调度分2种:

  1.  分时:CPU分配给线程的执行时间都一样长,所有线程轮流使用CPU 的使用权,分配给自己的时间到了,即便程序没有运行完,也会切换到下一个线程
  2. 抢占式:优先让优先级高的线程使用 CPU,如线程优先级相同,则随机选择一个线程执行,Java使用的为抢占式调度 

那么线程池的最大创建数的定义又跟cpu有什么关系呢?这跟运行什么类型的程序有关!

CPU密集型

    指计算密集型的程序。该任务需进行大量的计算,主要消耗CPU资源,CPU占用率相当高。虽然可以用多线程完成,但任务越多,切换线程需花费时间就越多,效率降低。线程的应用场景:主要是复杂算法。

所以,要最高效的利用CPU,最大线程数:N(CPU核数) + 1

为什么要+1呢?《Java并发编程实战》一书中给出的原因是:即使当CPU密集型的线程偶尔由于页缺失故障或者其他原因而暂停时,这个“额外”的线程也能确保 CPU 的时钟周期不会被浪费。

你可以理解为:是一个备份的线程

IO密集型

   IO密集型任务指任务需要执行大量的IO操作,涉及到网络、磁盘IO操作,对CPU消耗较少。线程的应用场景主要是:数据库数据的交互,文件上传下载,网络数据传输等等

  • 磁盘 IO :针对磁盘的读写操作,比如文件的读写,假如数据库在本地的话,也属于磁盘 IO
  • 网络 IO :各种网络请求,比如 http 请求、远程数据库读写、远程 Redis 读写等等。

最大线程数:2*N(CPU核数)

课间小知识:如何查看CPU核心数呢?

一些单纯善良的小伙伴可能就马上打开Windows任务管理器,在那里数CPU核数了,emmmm....   运维部门的大刀已经向你挥舞了!自己电脑上的核数不等于服务器上的CPU核数,而且部署到不同的服务器,CPU核数可能都不一样,正确的姿势应该是通过代码获取:

Runtime.getRuntime().availableProcessors());

三、总结

1. CPU密集型:

充分利用CPU核心数。比如8核,线程数设置:8+1,最大的效率就是同时跑8个线程,另外一个当备份线程。如线程数远超过CPU核心数,会导致频繁的切换线程从而耗费较多时间

2. IO密集型:

IO操作并不占用CPU,不要让所有CPU闲下来,IO 的速度比起 CPU 是很慢的,此时线程数等于CPU核心数的两倍是最佳的

优秀的判断力来自经验,但经验来自于错误的判断。

核心线程数最大线程数是在多线程编程中常用的参,用于控制线程池中的线程数量。 核心线程数是指线程池中一直保持活动的线程数量,即使没有任务需要执行。最大线程数线程池中允许存在的最大线程数量,包括活动线程和等待队列中的线程。 在设置核心线程数最大线程数时,需要根据具体应用场景进行合理的配置,以充分利用系统资源并提高程序性能。 一般来说,可以根据以下几个因素来决定核心线程数最大线程数的设置: 1. CPU 核心数:如果你的应用主要是 CPU 密集型任务,可以将核心线程数设置为 CPU 核心数,以充分利用 CPU 资源。 2. I/O 密集型任务:如果你的应用主要是 I/O 密集型任务,例如网络请求或文件读写操作,可以根据系统的 I/O 能力来设置核心线程数最大线程数。一般建议将核心线程数设置为 CPU 核心数的两倍,以避免线程饥饿现象。 3. 内存限制:如果你的应用使用的是有限的内存资源,可以根据内存限制来设置最大线程数,避免因过多的线程导致内存溢出。 4. 并发量:根据你的应用并发量的预估,可以适当调整核心线程数最大线程数。如果并发量较高,可以适当增加线程数,以提高处理能力。 总之,核心线程数最大线程数的设置需要根据具体的应用场景和硬件条件来进行合理调整,以达到最佳的性能和资源利用率。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值