1
0
This commit is contained in:
2024-09-19 14:34:13 +03:00
parent 26ce772cd0
commit f06789d6de
3 changed files with 148 additions and 41 deletions

View File

@@ -0,0 +1,28 @@
package ru.lionarius;
import java.util.function.Function;
public class CalculationThread extends Thread {
private final IntegralCalculator calculator;
private final Function<Double, Double> function;
private final double lowerBound;
private final double upperBound;
private double result;
public CalculationThread(IntegralCalculator calculator, Function<Double, Double> function, double lowerBound, double upperBound) {
this.calculator = calculator;
this.function = function;
this.lowerBound = lowerBound;
this.upperBound = upperBound;
}
@Override
public void run() {
this.result = this.calculator.calculate(this.function, this.lowerBound, this.upperBound);
}
public double getResult() {
return this.result;
}
}

View File

@@ -94,6 +94,9 @@ public class IntegralCalculator {
var sum = (function.apply(lowerBound) + function.apply(upperBound)) / 2; var sum = (function.apply(lowerBound) + function.apply(upperBound)) / 2;
for (var i = 1L; i < n; i++) { for (var i = 1L; i < n; i++) {
if (Thread.interrupted())
break;
sum += function.apply(lowerBound + h * i); sum += function.apply(lowerBound + h * i);
this.callProgressCallback(i, n); this.callProgressCallback(i, n);

View File

@@ -1,54 +1,130 @@
package ru.lionarius; package ru.lionarius;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.function.Function; import java.util.function.Function;
public class Main { public class Main {
/**
* Counter to assign unique IDs to each calculation thread.
*/
private static int currentId = 0;
/**
* Map to store active calculation threads, with thread IDs as keys.
*/
private static final Map<Integer, CalculationThread> threads = new HashMap<>();
public static void main(String[] args) { public static void main(String[] args) {
Function<Double, Double> function = x -> Math.sin(x) * x; final Function<Double, Double> function = x -> Math.sin(x) * x;
var lowerBound = 0.0; final var lowerBound = 0.0;
var upperBound = 1.0; final var upperBound = 1.0;
double[] accuracies = {0.001, 0.00001, 0.0000001, 0.000000001, 0.000000001};
var threads = new Thread[accuracies.length];
for (var i = 0; i < accuracies.length; i++) { var scanner = new Scanner(System.in);
final var accuracy = accuracies[i];
var thread = new Thread(() -> {
var calculator = new IntegralCalculator(
accuracy,
(current, total) -> {
if (current % (total / 15) != 0)
return;
System.out.printf(
"[%s] Progress: %.2f%%%n",
Thread.currentThread().getName(),
(current * 100.0 / total)
);
}
);
var startTime = System.nanoTime(); while (true) {
System.out.println("Enter desired command (start <e>, stop <n>, await <n>, exit):");
var input = scanner.nextLine().trim();
var command = input.split(" ");
var value = calculator.calculate(function, lowerBound, upperBound); if (command.length == 0) {
System.out.println("No command entered.");
continue;
}
var totalTime = System.nanoTime() - startTime; try {
switch (command[0]) {
System.out.printf( case "start" -> handleStartCommand(command, function, lowerBound, upperBound);
"[%s] Calculated value: %.15f | Accuracy: %e | Time: %.9fms%n", case "stop" -> handleStopCommand(command);
Thread.currentThread().getName(), case "await" -> handleAwaitCommand(command);
value, case "exit" -> handleExitCommand();
accuracy, default -> System.out.println("Unknown command");
totalTime / 1_000_000.0 }
); } catch (NumberFormatException e) {
}); System.out.println("Invalid number format: " + e.getMessage());
threads[i] = thread; } catch (Exception e) {
thread.start(); System.out.println("Error executing command: " + e.getMessage());
} }
try {
for (var thread : threads)
thread.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} }
} }
/**
* Handles the "start" command. This starts a new thread to calculate
* the integral of the given function with the specified accuracy.
*
* @param command the command array where the second element is the desired accuracy
* @param function the mathematical function to be integrated
* @param lowerBound the lower bound of the integral
* @param upperBound the upper bound of the integral
*/
private static void handleStartCommand(String[] command, Function<Double, Double> function, double lowerBound, double upperBound) {
if (command.length < 2) {
System.out.println("Usage: start <accuracy>");
return;
}
double accuracy = Double.parseDouble(command[1]);
var thread = new CalculationThread(new IntegralCalculator(accuracy), function, lowerBound, upperBound);
int id = currentId++;
threads.put(id, thread);
System.out.println("Started calculation on thread " + id);
thread.start();
}
/**
* Handles the "stop" command. This stops and removes the calculation thread
* associated with the given ID.
*
* @param command the command array where the second element is the ID of the thread to stop
*/
private static void handleStopCommand(String[] command) {
if (command.length < 2) {
System.out.println("Usage: stop <threadId>");
return;
}
int id = Integer.parseInt(command[1]);
var thread = threads.remove(id);
if (thread == null) {
System.out.println("Thread " + id + " not found");
} else {
thread.interrupt();
System.out.println("Stopped thread " + id);
}
}
/**
* Handles the "await" command. This waits for the specified thread to finish
* its calculation and then prints the result.
*
* @param command the command array where the second element is the ID of the thread to await
*/
private static void handleAwaitCommand(String[] command) {
if (command.length < 2) {
System.out.println("Usage: await <threadId>");
return;
}
int id = Integer.parseInt(command[1]);
var thread = threads.remove(id);
if (thread == null) {
System.out.println("Thread " + id + " not found");
return;
}
try {
thread.join();
System.out.println("Result: " + thread.getResult());
} catch (InterruptedException e) {
System.out.println("Thread was interrupted while awaiting: " + e.getMessage());
}
}
/**
* Handles the "exit" command. This stops all active calculation threads and
* exits the application.
*/
private static void handleExitCommand() {
System.out.println("Shutting down...");
threads.values().forEach(CalculationThread::interrupt);
System.exit(0);
}
} }