Мне действительно нужна помощь по моему проекту. Задача: Целью теста является создание вычисления π (Pi) с использованием различных вычислительных процессов, ускоренных многопоточностью. Используйте класс BigDecimal для лучшей точности. Используйте свои собственные классы исключений и упакуйте все классы в одну аккуратную концепцию пакета.
Я пытался реализовать метод Leibniz, и моя главная проблема заключалась в том, что я не знаю, как остановить поток из моего основного метода, в то время как потоки бегут. Мой Учитель показал нам пример своего метода Миана, и вы можете ясно видеть, что он запускает метод, например, с 4 потоков. И через несколько секунд он может остановить все потоки. Вот его пример основного класса:
CalculatePi pi = new Leibniz();
System.out.println("Start: " + pi.getMethodName());
pi.startCalculation(4); //four threads
int prec = 0;
BigDecimal result = BigDecimal.ZERO;
long timeStart = System.currentTimeMillis();
while(prec < MAX_PRECISION) {
someDelay(); //give some time to calculate
BigDecimal newResult = pi.getValue();
int newPrec = precicion(result, newResult);
if(newPrec != prec) {
System.out.println("pi (" + newPrec + "): " + newResult);
prec = newPrec;
}
result = newResult;
}
long timeStop = System.currentTimeMillis();
pi.stopCalculation();
System.out.println( (timeStop - timeStart) + " ms");
System.out.println(pi.getInternalSteps() + " calulation steps");
Вот мои первые идеи для реализации задачи (не запутайтесь, я в основном сосредоточен на методах "startCalculation (int numThreads)" и "stopCalculation ()" которые оба даются интерфейсом)
// Methode soll Leibniz Verfahren mit mehreren Threads berechnen
@Override
public boolean startCalculation(int numThreads) {
// Threads müssen in Array gespeichert werden um damit zu arbeiten
LeibnizThread[] threadSpeicher = new LeibnizThread[numThreads];
for(int i = 0; i < numThreads; i++) {
// Neuen Thread initialisieren und im Array speichern
threadSpeicher[i] = new LeibnizThread(numThreads, i);
//Thread starten
threadSpeicher[i].start();
}
//Warten bis alle Threads fertig sind und ihr ergebnis berechnet haben
for(LeibnizThread w : threadSpeicher)
try {
w.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BigDecimal sum = new BigDecimal(0.0);
//Summe aller Threads zusammenrechnen
for(LeibnizThread w : threadSpeicher) {
System.out.println(w.getResult() + " Zwischenergebnis");
sum = sum.add(w.getResult());
}
//Summe wird mit 4 multipliziert, um finales Ergebnis zu erhalten
this.value = sum.multiply(new BigDecimal(4));
System.out.println("Ergebnis: " + this.value);
return true;
}
//Methode soll Threads aus Methode startCalculation(numThreads) stoppen, aber wie ?
@Override
public void stopCalculation() {
flag = true;
}
И мой класс Thread выглядит так:
public class LeibnizThread extends Thread {
private int threadRemainder;
private int numThreads;
private BigDecimal result = new BigDecimal(0.0);
private volatile boolean flag = false;
public LeibnizThread(int threadCount, int threadRemainder) {
this.numThreads = threadCount;
this.threadRemainder = threadRemainder;
}
public void run() {
BigDecimal counter = new BigDecimal("1");
while( !flag ) {
if(counter.intValue() % numThreads == threadRemainder)
if(counter.remainder(new BigDecimal("2")).equals(BigDecimal.ONE)) {
result = result.add(BigDecimal.ONE.divide(((new BigDecimal("2").multiply(counter).subtract(BigDecimal.ONE))), 100, RoundingMode.HALF_UP));
}else {
result = result.subtract(BigDecimal.ONE.divide(((new BigDecimal("2").multiply(counter).subtract(BigDecimal.ONE))), 100, RoundingMode.HALF_UP));
}
counter = counter.add(new BigDecimal("1"));
}
}
public BigDecimal getResult() {
return this.result;
}
public void setFlagTrue() {
flag = true;
}
} Я пытался реализовать «флаг», чтобы остановить его, но я не знать, как получить влияние на потоки, которые инициализируются в методе «startCalculation (numThreads)» из метода «stopCalculation ()».
Если у кого-то есть идея, пожалуйста, дайте мне знать. Хорошего дня и будьте здоровы :)