gpt4 book ai didi

java - 多线程增加计算时间 - Java

转载 作者:搜寻专家 更新时间:2023-11-01 02:24:09 24 4
gpt4 key购买 nike

我被要求根据线程数检查计算时间来解决这个问题。因此我编写了一个使用蒙特卡洛方法计算积分的程序。我正在划分线程数的范围。之后,我统计线程,计算它们的部分,最后对部分结果求和以获得一般结果。

问题是计算时间随着线程数量的增加而不是减少(i7 处理器,Windows 7)

几个人在做这件事,我们不知道为什么会这样。我希望有人能给我一个建议。我附上代码:

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentLinkedQueue;


public class Runner {

private static final int MAXT = 10; // maksymalna ilość wątków
static PrintWriter outM;
static PrintWriter outMTime;

public static void main(String[] args){

double xp = 2;
double xk = 3;




filesOp();

// Wypisywanie kolumn tabeli
for(int threadNumber=1; threadNumber<=MAXT; threadNumber++){
outM.print("\t"+ threadNumber);
outMTime.print("\t"+ threadNumber);
}

double time1;
double time2;

//double startTime=System.currentTimeMillis(); // Przed wystartowaniem programu

for(int n=10000; n<=10000000; n=n*10){

System.out.println("Licze dla: " + n + " punktow.");


outM.print("\n"+n);
outMTime.print("\n"+n);


for(int threadNumber=1; threadNumber<=MAXT; threadNumber++){

outM.print("\t");
outMTime.print("\t");

time1=System.nanoTime();
multiThread(xp, xk, n, threadNumber);
time2=System.nanoTime();

outMTime.print((time2-time1)/1000000);
// czas pracy dla danej liczby wątków

}

}

outM.close();
outMTime.close();

}


public static void multiThread(double xp, double xk, int n, int threadNumber){
// Funkcja licząca całkę wielowątkowo.
// Całka do policzenia jest dzielona pomiędzy wątki

ArrayList<Thread> threadList = new ArrayList<Thread>();
ConcurrentLinkedQueue<Double> results = new ConcurrentLinkedQueue<Double>();

for(int i=0; i<threadNumber; i++){

MonteCarlo mc = new MonteCarlo( xp+(i*((xk-xp)/threadNumber)), xp+((i+1)*((xk-xp)/threadNumber)), (int)(n/threadNumber), results);


Thread t = new Thread(mc);
threadList.add(t);
t.start();

}

//for(int j=0; j<threadNumber; j++){ // pętla czeka na zakończenie wątków
for(Thread t : threadList){
try {
//while(t.isAlive()){}
//threadList.get(j).join();
t.join();
} catch (Exception e) {
e.printStackTrace();
}

}


double wynik = 0;
//for(int k=0; k<results.size(); k++){
for(double r: results){
//wynik = wynik + results.remove();
wynik= wynik + r;
}


outM.print(wynik);
}



public static void filesOp(){
File fileTemp;

fileTemp = new File("wyniki.txt");
if (fileTemp.exists()) fileTemp.delete();


fileTemp = new File("pomiary.txt");
if (fileTemp.exists()) fileTemp.delete();


try {

outM = new PrintWriter(new FileWriter("wyniki.txt", true));
outMTime = new PrintWriter(new FileWriter("pomiary.txt", true));
} catch (Exception e) {
e.printStackTrace();
}
}


}


public class MonteCarlo implements Runnable{

double xp;
double xk;
long n;
ConcurrentLinkedQueue<Double> results;

MonteCarlo(double xp, double xk, long n, ConcurrentLinkedQueue<Double> results){
this.xp=xp;
this.xk=xk;
this.n=n;
this.results=results;
}

//funkcja dla ktorej obliczamy calke
private static double func(double x) {
return x*x+3;
}


private static double funcIn(double x, double y) {
if (( y > 0) && (y <= func(x)))
return 1;
else if (( y > 0) && (y <= func(x)))
return -1;
return 0;
}

//random number from a to b
private static double randomPoint(double a, double b) {
return a + Math.random() * (b-a);
}

public void run(){
double yp, yk, calka;
int pointsIn;


yp = 0;
yk = Math.ceil(Math.max(func(xp), func(xk)));

pointsIn = 0;

for (long i=0; i<n; i++) {
pointsIn += funcIn(randomPoint(xp, xk), randomPoint(yp, yk));
}

calka = (pointsIn / (double)n) * ((xk-xp) * (yk-yp));

results.add(calka);

}


}

结果示例:

1 2 3 4 5 6 7 8 9 10

10000 6.185818 2.821405 3.721287 3.470309 4.068365 3.604195 4.323075 4.192455 6.159694 4.239105

100000 10.994522 15.874134 34.992323 40.851124 36.199631 49.54579 45.122417 61.427132 55.845435 60.7661

1000000 108.653008 274.443662 340.274574 407.054352 437.455361 469.853467 496.849012 584.519687 571.09329 594.152023

10000000 1066.059033 2877.947652 3600.551966 4175.707089 4488.434247 5081.572093 5501.217804 6374.335759 6128.274553 6339.043475

最佳答案

问题最有可能出在

private static double randomPoint(double a, double b) {
return a + Math.random() * (b-a);
}

Math.random() 在竞争激烈的情况下表现不佳。如果您使用的是 Java 7 或更高版本,请尝试以下操作:

private static double randomPoint(double a, double b) {
return ThreadLocalRandom.current().nextDouble(a, b);
}

关于java - 多线程增加计算时间 - Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29844882/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com