lab 4
This commit is contained in:
28
src/main/java/ru/lionarius/CalculationThread.java
Normal file
28
src/main/java/ru/lionarius/CalculationThread.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -94,6 +94,9 @@ public class IntegralCalculator {
|
||||
|
||||
var sum = (function.apply(lowerBound) + function.apply(upperBound)) / 2;
|
||||
for (var i = 1L; i < n; i++) {
|
||||
if (Thread.interrupted())
|
||||
break;
|
||||
|
||||
sum += function.apply(lowerBound + h * i);
|
||||
|
||||
this.callProgressCallback(i, n);
|
||||
|
||||
@@ -1,54 +1,130 @@
|
||||
package ru.lionarius;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.function.Function;
|
||||
|
||||
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) {
|
||||
Function<Double, Double> function = x -> Math.sin(x) * x;
|
||||
var lowerBound = 0.0;
|
||||
var upperBound = 1.0;
|
||||
double[] accuracies = {0.001, 0.00001, 0.0000001, 0.000000001, 0.000000001};
|
||||
var threads = new Thread[accuracies.length];
|
||||
final Function<Double, Double> function = x -> Math.sin(x) * x;
|
||||
final var lowerBound = 0.0;
|
||||
final var upperBound = 1.0;
|
||||
|
||||
for (var i = 0; i < accuracies.length; i++) {
|
||||
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 scanner = new Scanner(System.in);
|
||||
|
||||
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);
|
||||
|
||||
var totalTime = System.nanoTime() - startTime;
|
||||
|
||||
System.out.printf(
|
||||
"[%s] Calculated value: %.15f | Accuracy: %e | Time: %.9fms%n",
|
||||
Thread.currentThread().getName(),
|
||||
value,
|
||||
accuracy,
|
||||
totalTime / 1_000_000.0
|
||||
);
|
||||
});
|
||||
threads[i] = thread;
|
||||
thread.start();
|
||||
if (command.length == 0) {
|
||||
System.out.println("No command entered.");
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
for (var thread : threads)
|
||||
thread.join();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
switch (command[0]) {
|
||||
case "start" -> handleStartCommand(command, function, lowerBound, upperBound);
|
||||
case "stop" -> handleStopCommand(command);
|
||||
case "await" -> handleAwaitCommand(command);
|
||||
case "exit" -> handleExitCommand();
|
||||
default -> System.out.println("Unknown command");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
System.out.println("Invalid number format: " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error executing command: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user