如何用Java编写多线程PI计算程序?
我需要创建一个程序,使用Java多线程计算常数PI的近似值 我打算用Gregory Leibniz级数来计算PI/4的结果,然后乘以4得到PI近似值 但我对这个项目有些担心:如何用Java编写多线程PI计算程序?,java,multithreading,pi,approximation,Java,Multithreading,Pi,Approximation,我需要创建一个程序,使用Java多线程计算常数PI的近似值 我打算用Gregory Leibniz级数来计算PI/4的结果,然后乘以4得到PI近似值 但我对这个项目有些担心: 如何分离计算过程,以便为程序实现多线程处理?因为公式是求和的,我不知道如何把它们分成几部分,最后我会把它们全部收集起来 我在考虑这样一个事实,即程序将无限执行公式,因此用户需要提供一些配置执行的方法,以确定何时停止并返回结果。有可能吗?我该怎么做 到目前为止,这是我能做的最多的了 public class PICalcu
public class PICalculate {
public static void main(String[] args) {
System.out.println(calculatePI(5000000) * 4);
}
static double calculatePI(int n) {
double result = 0.0;
if (n < 0) {
return 0.0;
}
for (int i = 0; i <= n; i++) {
result += Math.pow(-1, i) / ((2 * i) + 1);
}
return result;
}
}
公共类PICalculate{
公共静态void main(字符串[]args){
系统输出打印项次(calculatePI(5000000)*4);
}
静态双计算EPI(整数n){
双结果=0.0;
if(n<0){
返回0.0;
}
对于(int i=0;i来说,最直接但不是最理想的方法是在线程之间分配序列元素。例如,如果有4个线程,线程1将使用n%4==0个元素,线程2将使用n%4==1个元素,依此类推
public static void main(String ... args) throws InterruptedException {
int threadCount = 4;
int N = 100_000;
PiThread[] threads = new PiThread[threadCount];
for (int i = 0; i < threadCount; i++) {
threads[i] = new PiThread(threadCount, i, N);
threads[i].start();
}
for (int i = 0; i < threadCount; i++) {
threads[i].join();
}
double pi = 0;
for (int i = 0; i < threadCount; i++) {
pi += threads[i].getSum();
}
System.out.print("PI/4 = " + pi);
}
static class PiThread extends Thread {
private final int threadCount;
private final int threadRemainder;
private final int N;
private double sum = 0;
public PiThread(int threadCount, int threadRemainder, int n) {
this.threadCount = threadCount;
this.threadRemainder = threadRemainder;
N = n;
}
@Override
public void run() {
for (int i = 0; i <= N; i++) {
if (i % threadCount == threadRemainder) {
sum += Math.pow(-1, i) / (2 * i + 1);
}
}
}
public double getSum() {
return sum;
}
}
publicstaticvoidmain(String…args)抛出InterruptedException{
int threadCount=4;
int N=100_000;
PiThread[]threads=新的PiThread[threadCount];
对于(int i=0;i 对于(int i=0;i)该数列收敛得非常慢……我想你对线程理解得不太好,所以回去阅读教科书并练习一些示例。多线程方法的一个问题是,为了获得好的结果,需要首先添加小项,这是由于浮点舍入。还要注意,该数列非常慢收敛。@Bathsheba“先加小项”是什么意思?这是浮点运算的一个怪癖。将一个非常小的数字加到一个非常大的数字上,计算结果将简单地变成一个更大的数字。因此,在对一系列的项求和时,你需要小心:你需要先从小项开始。Long.MAX_值的限制是什么?还有,如何计算第二种方法有效吗?每个线程将等待另一个线程死亡的时间,然后继续执行?我仍然不知道每个线程如何保持自己的结果,而另一个线程如何不执行之前的计算?我注意到,在第二种方法中,程序在完成计算后不会退出。Long.MAX_值限制了该数字序列中的元素。所有线程同时运行,在相应的变量中保留部分和。在互补线程执行完成或超时中断后,所有部分和将相加。如果您是对的,则以不同的方式中断线程是正确的,因为join不会杀死它们。您可以将isInterrupted check添加到while循环中,并在连接后中断它们。不需要新线程。键盘截取在主线程中完成。例如,您可以使用thread.sleep(5_000)
替换Scanner-Keyboard=new Scanner(System.in);System.out.println(“按Enter停止计算”);Keyboard.next();
public void run() {
for (int i = threadRemainder; i <= N; i += threadCount) {
sum += Math.pow(-1, i) / (2 * i + 1);
}
}
public static volatile boolean running = true;
public static void main(String ... args) throws InterruptedException {
int threadCount = 4;
long timeoutMs = 5_000;
final AtomicLong counter = new AtomicLong(0);
PiThread[] threads = new PiThread[threadCount];
for (int i = 0; i < threadCount; i++) {
threads[i] = new PiThread(counter);
threads[i].start();
}
Thread.sleep(timeoutMs);
running = false;
for (int i = 0; i < threadCount; i++) {
threads[i].join();
}
double sum = 0;
for (int i = 0; i < threadCount; i++) {
sum += threads[i].getSum();
}
System.out.print("counter = " + counter.get());
System.out.print("PI = " + 4*sum);
}
static class PiThread extends Thread {
private AtomicLong counter;
private double sum = 0;
public PiThread(AtomicLong counter) {
this.counter = counter;
}
@Override
public void run() {
long i;
while (running && isValidCounter(i = counter.getAndAdd(1))) {
sum += Math.pow(-1, i) / (2 * i + 1);
}
}
private boolean isValidCounter(long value) {
return value >= 0 && value < Long.MAX_VALUE;
}
public double getSum() {
return sum;
}
}