Java多线程计算某个范围内的质数

来源:互联网 发布:linux的vim命令 编辑:程序博客网 时间:2024/06/05 14:07

程序功能说明:计算某个范围内的质数,分别用单线程和多线程实现,比较计算时间。

抽象类AbstractPrimeFinder:计算质数的父类,isPrime(final int number)用来判断传入的int值是否是质数,countPrimesInRange(final int lower,final int upper)通过调用isPrime()方法计算某一范围内质数的数量,timeAndCompute()方法用来统计和输出计算质数花费的时间。

//抽象类AbstractPrimeFinderabstract class AbstractPrimeFinder {public boolean isPrime(final int number) {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 int upper) {int total = 0;for (int i = lower; i <= upper; i++)if (isPrime(i))total++;return total;}public void timeAndCompute(final int number) {final long start = System.nanoTime();final long numberOfPrimes = countPrimes(number);final long end = System.nanoTime();System.out.printf("Number of primes under %d is %d\n", number,numberOfPrimes);System.out.println("Time (seconds) taken is " + (end - start) / 1.0e9);}public abstract int countPrimes(final int number);}/***单线程代码*/public class SequentialPrimeFinder extends AbstractPrimeFinder {        //重写父类的countPrimes方法public int countPrimes(final int number) {return countPrimesInRange(1, number);}public static void main(final String[] args) {                //调用timeAndCompute方法,输出1千万以内的质数和计算用时new SequentialPrimeFinder().timeAndCompute(10000000);}}/*单线程下的执行结果Number of primes under 10000000 is 664579Time (seconds) taken is 7.518444261*/         

双线程代码

         package com.mime;import java.util.ArrayList;import java.util.List;import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.TimeUnit;public class ConcurrentPrimeFinder extends AbstractPrimeFinder {        //定义每个线程计算范围内的数字的数量private final int poolSize;        //定义线程数量private final int numberOfParts;        //线程构造方法,根据起始点和计算数量public ConcurrentPrimeFinder(final int thePoolSize,final int theNumberOfParts) {poolSize = thePoolSize;numberOfParts = theNumberOfParts;}        //重写countPrimes方法public int countPrimes(final int number) {int count = 0;try {final List<Callable<Integer>> partitions = new ArrayList<Callable<Integer>>();final 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<Integer>() {public Integer call() {return countPrimesInRange(lower, upper);}});}final ExecutorService executorPool = Executors.newFixedThreadPool(poolSize);final List<Future<Integer>> resultFromParts = executorPool.invokeAll(partitions, 10000, TimeUnit.SECONDS);executorPool.shutdown();for (final Future<Integer> result : resultFromParts)count += result.get();} catch (Exception ex) {throw new RuntimeException(ex);}return count;}        //测试结果public static void main(final String[] args) {                       //调用timeAndCompute方法,输出1千万以内的质数和计算用时new ConcurrentPrimeFinder(4,100).timeAndCompute(10000000);}} 输出Number of primes under 10000000 is 664579Time (seconds) taken is 3.825282456                      可以根据cpu个数和调整分区树来调优这个线程数来达到最有效果。