1,首先确定自己的核心数,通过下面代码可以很容易确认:
Runtime.getRuntime().availableProcessors()
2,基础方法
/** * @author cjm * @date 2018/5/15 */ public abstract 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 timeAndCompure(final int number){ final long start =System.nanoTime(); final long numberOfPrimes=countPrimes(number); final long end = System.nanoTime(); System.out.printf("Nubmer of primes under %d is %d \n",number,numberOfPrimes); System.out.println("Time(seconds) taken is "+(end-start)/1.0e9); } public abstract int countPrimes(int number); }
3,开线程计算
import java.util.concurrent.*; import java.util.*; /** * @author cjm * @date 2018/5/15 */ 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; } @Override public int countPrimes(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>() { @Override public Integer call() throws Exception { 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 e) { throw new RuntimeException(e); } return count; } public static void main(String[] args) { args = new String[3]; args[0] = "10000000"; args[1] = "4"; args[2] = "20"; if (args.length < 3) { System.out.println("Usage:number poolsize numberOfParts"); } else { new ConcurrentPrimeFinder(Integer.parseInt(args[1]), Integer.parseInt(args[2])).timeAndCompure(Integer.parseInt(args[0])); } } }