计算程序所需线程总数 -- 摘自《Java虚拟机并发编程》

本文探讨如何根据任务的阻塞系数计算程序所需的线程总数。阻塞系数从0到1,计算密集型任务为0,IO密集型任务接近1。通过分析工具或API获取线程在系统I/O与CPU密集任务的时间比,以确定合适的线程数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

计算程序所需线程总数:
线程数 = CPU可用核心数/(1-阻塞系数)

其中阻塞系数的取值在0-1之间。

计算密集型任务的阻塞系数为0,而IO密集型任务的阻塞系数则接近于1。一个完全阻塞的任务是注定要挂掉的,所以我们无须担心阻塞系数会达到1。

为了更好的确定程序所需线程数,我们需要知道下面两个关键参数:
1、处理器可用核心数

2、任务的阻塞系数

第一个参数很容易确定(Runtime.getRuntime().availableProcessors())。

阻塞系数可以采用一些性能分析工具或java.lang.managenment API来确定线程话在系统I/O操作上的时间与CPU密集任务所消耗的时间比值。

Demo:

	// 测试公式:线程数=CPU可用核心数/(1-阻塞系数)
	@Test
	public void testInvokeAll() throws InterruptedException, ExecutionException {
		// 向 Java 虚拟机返回可用处理器的数目(我当前机器是i3双核四线程,返回为4)
		int numberOfCores = Runtime.getRuntime().availableProcessors();
		double blockingCoefficient = 0;
		int poolSize = (int) (numberOfCores / (1 - blockingCoefficient));
		System.out.println("poolSize:" + poolSize);

		// 创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程
		ExecutorService services = Executors.newFixedThreadPool(poolSize);

		List<Callable<String>> tasks = new LinkedList<Callable<String>>();
		for (int i = 10; i >= 1; i--) {
			final String reStr = "current call " + i;
			final int j = i;

			tasks.add(new Callable<String>() {

				@Override
				public String call() throws Exception {
					// 模拟阻塞
					TimeUnit.SECONDS.sleep(j);
					return reStr;
				}
			});
		}

		long beginTime = System.currentTimeMillis();

		List<Future<String>> invokeValues = services.invokeAll(tasks);

		System.out.println("time:" + (System.currentTimeMillis() - beginTime));

		Iterator<Future<String>> iter = invokeValues.iterator();
		while (iter.hasNext()) {
			System.out.println(iter.next().get());
		}

		services.shutdown();
	}
当我们阻塞系数设置为0,消耗时间为15003;阻塞系数设置为0.9时,消耗时间为10001。

poolSize:4
time:15003
current call 10
current call 9
current call 8
current call 7
current call 6
current call 5
current call 4
current call 3
current call 2
current call 1

poolSize:40
time:10001
current call 10
current call 9
current call 8
current call 7
current call 6
current call 5
current call 4
current call 3
current call 2
current call 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值