public class ComputeCoreThread {
private static double mintaskCount = 30;
private static double taskTime = 2;
private static double taskWaitTime = 60;
private static double cpuTime = 0.5;
private static int cpu = 40;
public static void main(String[] args) {
// taskTime / cpuTime = 一个线程可以执行多少个任务
double coreThread = mintaskCount/(taskTime / cpuTime);
// 操作系统的最大出力速度
double maxCoreThread = (taskTime / cpuTime) * cpu;
// (coreThread / cpuTime * taskTime) = 核心线程在一个任务期间内可以处理的任务数
double length = (coreThread / cpuTime * taskTime) * taskWaitTime;
System.out.println("coreThread =" + coreThread);
System.out.println("maxCoreThread =" + maxCoreThread);
System.out.println("queue length =" + length);
}
}
**最大线程数目 **
( 任务执行总时间 / 线程CPU时间 )* CPU数目
如何理解这句话呢?说一下我的理解吧。
(1.5+0.5)/0.5*4 = 32
假设每个任务执行需要2秒,其中cpu计算0.5秒,io计算1.5秒。1.5+05=任务执行总时间。但是线程A在执行io操作的时候比如说等待数据库返回数据 等待其他系统接口数据,那么他会阻塞且出让cup使用权给其他的线程执行计算操作。也就是在1.5秒的等待时间内cup可以切换3次时间片给不同的线程,每个线程执行0.5秒的计算操作(当然这里有线程上下文切换的时间消耗,暂不考虑)。那么1个cpu在一个任务时间2秒内能够执行多少次cpu计算呢?2/0.5 = 4次。其实我们的最终目的是让cup不能停歇,让cpu一直的运算才能达到最大的效率。所以一个cup在2秒内可以切换4次上下文也就是可以同时切换4个线程执行4个任务,那么4核cpu也就 4*8 =32。 启动32个线程在2秒内可以处理32个任务。
核心线程数
80%时间系统接受的任务数 / ( 任务执行的总时间 / 任务执行总cpu计算的时间 )
30/(2/0.5) = 7.5
我理解核心线程数就是列队中缓存的线程,最好不要把它跟最大线程数设置为同一个,因为这样子会导致线程池中多余的线程处于空闲状态从而浪费。那么什么多少是合理的呢?假如系统80%的时候接受的任务数是30,每个任务执行时间是2秒其中cpu运算时间是0.5秒。那么理想状态下一个线程2秒内可以处理2/0.5个任务。30/(2/0.5)得到20个任务需要多少线程可以处理。
列队长度
(核心线程处理的cpu计算次数 * 任务执行时长 ) * 在列队中等待的最长时间
(10/0.5x2)*60
列队长度不能设置太大,太大容易引起内存泄露,需要根据实际情况来确定。假如任务中cpu计算执行时间是0.5秒,核心线程数是10,那么 10/0.5 等价于10个线程可以处理的cpu计算次数,假如1个任务的执行总时间是2秒,那么10/0.5x2 等价于1个任务期间内核心线程可以处理的任务数。我们的任务一旦放入到列队中,根据先入先出原则会一直等待直到任务被消费,假如我们的任务最多在列队中等待60秒,那么按照理想情况下列队中的任务最多等待60秒就应该被线程消费且执行,所以列队长度 (10/0.5x2)*60 =2400
网友评论