java多线程计算pi_java 多线程学习笔记(一) -- 计算密集型任务

最近在看《Java虚拟机并发编程》,在此记录一些重要的东东。

线程数的确定:

1. 获取系统可用的处理器核心数:int numOfCores = Runtime.getRuntime().availableProcessors()

2. 如果任务是计算密集型的,则线程数 = numOfCores

如果任务是IO密集型的,则线程数 = numOfCores / (1 - 阻塞系数), 其中阻塞系数在0~1之间。

注:如果任务被阻塞的时间大于执行时间, 则这些任务是IO密集型的,我们就需要创建比处理器核心数大几倍数量的线程

在解决问题的过程中使处理器一直保持忙碌状态比将负载均摊到每个子任务要实惠得多。

任务完成并不代表线程消亡。

计算密集型任务:如求1到10000000内所有素数的个数

1. AbstractPrimeFinder

public abstract classAbstractPrimeFinder {public boolean isPrime(final intnumber){if(number <= 1) return false;for(int i = 2; i <=Math.sqrt(number); i++){if (number % i == 0)return false;

}return true;

}public int countPrimesInRange(final int lower, final intupper){int total = 0;for( int i = lower; i <= upper; i++){if(isPrime(i))

total++;

}returntotal;

}public void timeAndComputer(final intnumber){long start =System.nanoTime();int numberOfPrimes =countPrimes(number);long end =System.nanoTime();

System.out.printf("Number of primes under %d is %d\n", number, numberOfPrimes);

System.out.println("Spend time(seconds) is " + (end-start)/1.0e9);

}public abstract int countPrimes(final intnumber);

}

2. ConcurrentPrimeFinder

/*** 对于计算密集型的任务,增加线程数并没有什么意义,线程数应该等于CPU内核数。如果较难把任务均摊到CPU,则

* 可以把任务切分成较多块,以确保CPU完成某块任务后,可以继续处理其它块。防止某个CPU完成任务后处于空闲状态。

*@authorshj

**/

public class ConcurrentPrimeFinder extendsAbstractPrimeFinder{private final intpoolSize;private final intnumberOfParts;public ConcurrentPrimeFinder(int poolSize, intnumberOfParts){this.poolSize =poolSize;this.numberOfParts =numberOfParts;

}

@Overridepublic int countPrimes(final intnumber) {int count = 0;try{

List> partitions = new ArrayList<>();int chunksPerPartition = number /numberOfParts;for(int i = 0; i < numberOfParts; i++){final int lower = (i * chunksPerPartition) + 1;final int upper = (i == numberOfParts - 1) ? number : lower + chunksPerPartition - 1;

partitions.add(new Callable(){publicInteger call(){returncountPrimesInRange(lower, upper);

}

});

}

ExecutorService executorPool=Executors.newFixedThreadPool(poolSize);

List> results = executorPool.invokeAll(partitions, 10000, TimeUnit.SECONDS);

executorPool.shutdown();for(Futureresult : results){

count+=result.get();

}

}catch(Exception e){

e.printStackTrace();

}returncount;

}public static voidmain(String[] args){int cores =Runtime.getRuntime().availableProcessors();int numberOfParts = 20; //划分成子区间的数量, 修改此值查看运行时间的变化

newConcurrentPrimeFinder(cores,numberOfParts).timeAndComputer(10_000_000);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值