Folgendes kurze Programm gibt eine Näherung für Pi aus. Dabei wird der Monte-Carlo-Algorithmus benutzt, der durch eine sich sehr oft wiederholende Schleife die CPU voll auslastet.
Nach ca. 1500ms terminiert auf meinem Rechner dieses Programm. Die CPU-Auslastung steigt auf einem Quadcore-Rechner auf 25%, da logischerweise nur ein Kern damit beschäftigt ist.
Um die Sache etwas effektiver zu gestalten, habe ich mir gedacht, das wäre ein ideals Beispiel, um Multithreading in Java auszuprobieren.
Das Programm lastet nun zwei Kerne zu 100% aus, braucht aber enttäuschenderweise mit ca. 4000ms wesentlich länger als das Singlethreading-Programm.
Wie ist das zu erklären? Bzw. wo liegt mein Fehler?
Java:
public class Bsp1 {
public static void main(String[] args) {
int dotsSquare = 10000000, dotsCircle = 0;
double cordX, cordY, pi;
long time = System.currentTimeMillis();
for (int i=0; i<dotsSquare; i++) {
cordX = Math.random();
cordY = Math.random();
if (cordX*cordX + cordY*cordY <= 1.0)
dotsCircle++;
}
pi = (4.0*dotsCircle)/dotsSquare;
System.out.println("Laufzeit: " + (System.currentTimeMillis()-time) + "ms");
System.out.println("Näherung PI: " + pi);
}
}
Nach ca. 1500ms terminiert auf meinem Rechner dieses Programm. Die CPU-Auslastung steigt auf einem Quadcore-Rechner auf 25%, da logischerweise nur ein Kern damit beschäftigt ist.
Um die Sache etwas effektiver zu gestalten, habe ich mir gedacht, das wäre ein ideals Beispiel, um Multithreading in Java auszuprobieren.
Java:
public class Bsp2 {
public static void main(String[] args)
{
int dots = 10000000;
double pi;
Calculation c1 = new Calculation(dots/2);
Calculation c2 = new Calculation(dots/2 + dots%2);
Thread t1 = c1;
Thread t2 = c2;
long time = System.currentTimeMillis();
t1.start();
t2.start();
try {
t2.join();
t1.join();
System.out.println("Beide Threads beendet");
System.out.println();
} catch (Exception e) {
System.out.printf("Fehler: " + e.toString());
}
pi = 4.0*(c1.dotsCircle+c2.dotsCircle)/dots;
System.out.println("Laufzeit: " + (System.currentTimeMillis()-time) + " ms");
System.out.println("1. Ergebnis: " + c1.dotsCircle);
System.out.println("2. Ergebnis: " + c2.dotsCircle);
System.out.printf("Näherung PI: " + pi);
}
}
class Calculation extends Thread {
public Calculation(int dots) {
dotsSquare = dots;
nr = cnt++;
}
private int dotsSquare;
public int dotsCircle = 0;
int nr;
static private int cnt = 1;
@Override public void run()
{
System.out.println(nr + ". Thread startet");
double cordX, cordY;
for (int i=0; i<dotsSquare; i++) {
cordX = Math.random();
cordY = Math.random();
if (cordX*cordX + cordY*cordY <= 1.0)
dotsCircle++;
}
System.out.println(nr + ". Thread beendet");
}
}
Wie ist das zu erklären? Bzw. wo liegt mein Fehler?