1

I need to write a simple program that prints prime numbers up to the given number but no longer than 5 seconds. Is there some kind of timer to use to interrupt a method after a period of time? (but no interruption if printing is shorter than 5 sec). Thanks in advance.

My code:

public class Primes {
    private static boolean checkIfPrime(int x) {
        if (x == 2) return true;
        if (x % 2 == 0) return false;
        int sqrt = (int) Math.sqrt(x) + 1;
        for (int i = 3; i < sqrt; i = i + 2) if (x % i == 0) return false;
        return true;
    }

    private static void printPrimesAndOperationTime(int n) {
        long start = System.nanoTime();
        for (int i = 2; i <= n; i++) if (checkIfPrime(i)) System.out.println(i);
        long end = System.nanoTime();

        long timeResult = end - start;
        System.out.println("Printing time = " + timeResult + " [ns] => "
                + Math.round(timeResult * 100.0 / 1000000) / 100.0 + " [ms]");
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();

        printPrimesAndOperationTime(n);
    }
}
Zoe
  • 27,060
  • 21
  • 118
  • 148
Pawel
  • 27
  • 1
  • 5

2 Answers2

2

Used Java Concurrency APIs to solve the above problem. please find inline comments for code walk through.

import java.util.Scanner;
import java.util.concurrent.*;

public class TimeoutInterval {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newSingleThreadExecutor(); // Start Single thread executor
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        Future future = executor.submit(new Primes(n)); // Find prime no.
        try {
            future.get(5, TimeUnit.SECONDS); // Set the time out of the prime no. search task
            executor.shutdown();
        } catch (TimeoutException e) {
            executor.shutdown();
            System.out.println("Terminated!");
        }

        executor.shutdownNow();
    }
}

class Primes  implements Runnable {
    private final int number;

    Primes(int number) {
        this.number = number;
    }
    @Override
    public void run() {
        System.out.println("Started..");
        printPrimesAndOperationTime(number);
        System.out.println("Finished!");
    }

    private static boolean checkIfPrime(int x) {
        if (x == 2) return true;
        if (x % 2 == 0) return false;
        int sqrt = (int) Math.sqrt(x) + 1;
        for (int i = 3; i < sqrt; i = i + 2) if (x % i == 0) return false;
        return true;
    }

    private static void printPrimesAndOperationTime(int n) {
        long start = System.nanoTime();
        for (int i = 2; i <= n && !Thread.interrupted(); i++) if (checkIfPrime(i)) {
            System.out.println(i);
        }
        long end = System.nanoTime();

        long timeResult = end - start;
        System.out.println("Printing time = " + timeResult + " [ns] => "
                + Math.round(timeResult * 100.0 / 1000000) / 100.0 + " [ms]");
    }

}

QuickSilver
  • 3,915
  • 2
  • 13
  • 29
  • Thx! Now it interrupt the printing method after the given time. It seems to be the solution I needed! – Pawel Apr 25 '20 at 11:13
0

Using ExecutorService, you can submit a task with a timeout. On Receiving the TimeoutException, you should call cancel(true) method on the task to interrupt the thread.

From the documentation

... If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.

mtk
  • 13,221
  • 16
  • 72
  • 112