From f06789d6de87cdfba2f309b099d9b1506f7eeb65 Mon Sep 17 00:00:00 2001 From: lionarius Date: Thu, 19 Sep 2024 14:34:13 +0300 Subject: [PATCH] lab 4 --- .../java/ru/lionarius/CalculationThread.java | 28 ++++ .../java/ru/lionarius/IntegralCalculator.java | 3 + src/main/java/ru/lionarius/Main.java | 158 +++++++++++++----- 3 files changed, 148 insertions(+), 41 deletions(-) create mode 100644 src/main/java/ru/lionarius/CalculationThread.java diff --git a/src/main/java/ru/lionarius/CalculationThread.java b/src/main/java/ru/lionarius/CalculationThread.java new file mode 100644 index 0000000..248d316 --- /dev/null +++ b/src/main/java/ru/lionarius/CalculationThread.java @@ -0,0 +1,28 @@ +package ru.lionarius; + +import java.util.function.Function; + +public class CalculationThread extends Thread { + private final IntegralCalculator calculator; + private final Function function; + private final double lowerBound; + private final double upperBound; + + private double result; + + public CalculationThread(IntegralCalculator calculator, Function 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; + } +} diff --git a/src/main/java/ru/lionarius/IntegralCalculator.java b/src/main/java/ru/lionarius/IntegralCalculator.java index a69ae82..282d4b9 100644 --- a/src/main/java/ru/lionarius/IntegralCalculator.java +++ b/src/main/java/ru/lionarius/IntegralCalculator.java @@ -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); diff --git a/src/main/java/ru/lionarius/Main.java b/src/main/java/ru/lionarius/Main.java index 4498efa..88c62ab 100644 --- a/src/main/java/ru/lionarius/Main.java +++ b/src/main/java/ru/lionarius/Main.java @@ -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 threads = new HashMap<>(); + public static void main(String[] args) { - Function 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 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 , stop , await , 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; - - 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(); - } - - try { - for (var thread : threads) - thread.join(); - } catch (InterruptedException e) { - throw new RuntimeException(e); + try { + 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 function, double lowerBound, double upperBound) { + if (command.length < 2) { + System.out.println("Usage: start "); + 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 "); + 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 "); + 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); + } }