2

so I am making a java code testing web application and I am running each code execution in a seperate thread. The problem is that sometimes tests have a time limit or the student just writes an infinite while loop. I've tried to terminate my testing thread with "best practices" such as using interrupts but I have no control over the inner workings of my compilation function so I can't just tell the thread to look if it has been interrupted or not. I'd like advice on how to handle this situation better. Here is my bare bones example of what I want to achieve:


public class Main {
    public static void main(String[] args) {

        CodeExecutionThread cex = new CodeExecutionThread();

        cex.start();

        try {
            cex.join(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("Thread should stop at this point.");

    }
}


class CodeExecutionThread extends Thread {

    public CodeExecutionThread() {

    }

    @Override
    public void run() {

        infinite_operation();

    }

    public void infinite_operation() {
        while(true) {
            System.out.println("thread active");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

  • Is there a reason why the operation is infinite? Normally you would want to build in functionality to allow you to stop the thread. – JRSofty Jun 15 '20 at 08:52
  • 1
    You can't really force a thread to stop. You can "kindly ask it" to stop by interrupting it. The thread that is being interrupted needs to handle the interruption. – Amongalen Jun 15 '20 at 08:52
  • 1
    "while(true)" and you are wondering why there is an infinite loop? – Stultuske Jun 15 '20 at 08:52
  • 2
    @Stultuske The OP says it is a testing application where the code it executes is submitted by someone else which *could* be an infinite operation. The OP knows `while(true)` results in an infinite loop – Thiyagu Jun 15 '20 at 08:55
  • Have a look at - [How to timeout a thread](https://stackoverflow.com/questions/2275443/how-to-timeout-a-thread) – Thiyagu Jun 15 '20 at 08:59
  • If your application runs foreign code, it probably should do that in a subordinate process. Killing a process can be done safely and easily. – Ohm's Lawman Jun 15 '20 at 10:53

1 Answers1

1

I came accross the same problem more than once.

Probably not what you are looking for, but there is probably no better way than to use a flag inside the worker thread -- as described here for example: https://www.baeldung.com/java-thread-stop

When using a flag, there is of course a contract between the main thread and the worker -- you need to divide the infinite_operation into smaller chunks and check for the flag.

If you do not want that kind of contract or if it is not possible, consider using a process, which can be "safely" killed by OS (https://www.baeldung.com/java-process-api).

bubak
  • 1,464
  • 1
  • 13
  • 11
  • You don't need to do that: you just need to handle the InterruptedException in a way such that interrupting the thread means that it stops, e.g. put the try/catch outside the loop. – Andy Turner Jun 15 '20 at 09:52
  • True enough if you can check for `interrupted` status -- but you can check for the flag directly. Imho it provides better control when to quit (ie. state is consistent) and makes the purpose (stopping during the work) explicit. Handling the `InterruptedException` is of course a good practise. – bubak Jun 16 '20 at 08:40
  • What worked for me was simply using stop() to throw an exception and in my case that made the thread with the infinite operation stop. – Danijel Maraž Jun 16 '20 at 08:43