Java:多线程计算圆周率
public class Main {
public static double sum = 0.0;
public static void main(String[] args) throws ClassNotFoundException, InterruptedException, ExecutionException {
int tNum = 8;
int step = Integer.MAX_VALUE / 10000;
ExecutorService poor = Executors.newFixedThreadPool(tNum);
int begin = 1;
ArrayList<Future<Double>> list = new ArrayList<Future<Double>>();
for (int i = 0; i < tNum; i++) {
int start = begin + step * i;
int end = begin + step * (i + 1) - 1;
Callable<Double> caller = new Main().new MyCaller(start, end);
Future<Double> res = poor.submit(caller);
list.add(res);
}
poor.shutdown();
double sum = 0.0;
for (Future<Double> res : list) {
sum += res.get();
}
System.out.println(sum);
}
class MyCaller implements Callable<Double> {
private int start;
private int end;
MyCaller(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public Double call() throws Exception {
double sum = 0;
for (int n = start; n <= end; n++) {
sum += Math.pow(-1.0, n - 1) * 4.0 / (2.0 * n - 1.0);
}
return sum;
}
}
}
说明:
获取线程池服务对象,用于启动最多tNum个线程
ExecutorService的实例能够启动线程,并拿到线程执行结果。
ExecutorService poor = Executors.newFixedThreadPool(tNum);
将线程对象提交到线程池并启动,线程执行完成会返回结果。
Callable<Double> caller = new Main().new MyCaller(start, end);
Future<Double> res = poor.submit(caller);
关闭线程池,无法提交新任务,但是之前提交的任务会执行完成。若想之前提交的任务也结束执行调用
shutdownNow()
poor.shutdown();
等待线程池中线程运行完成并返回结果,此处会等待返回值完全返回,若无法返回则抛出异常。
res.get();
此处定义线程类,线程启动后执行call方法的代码,并返回一个值,这个值可以通过调用Future对象的get()方法拿到,Future对象是在将线程对象提交到线程池的时候返回的。
class MyCaller implements Callable<Double>{
@Override
public Double call() throws Exception {
return sum;
}
}