Question

How can I write a method of a class implementing the Runnable interface (started from an ExecutorService) that would interrupt the thread?

I know that I can use Future fut = es.submit(foo); (where es is the ExecutorService and foo is an instance of my class) and then call fut.cancel(true); from inside the main function of the application, but how do I call something like that from inside the class itself?

I would like to have in my Runnable class a method

public void stop() {…}

so that I can call foo.stop() from anywhere (including from the main function of the application) and it will work as if I had used the Future.cancel function (it has to raise ÌnterruptedException` if the thread is awaiting to acquire a Semaphore).

Was it helpful?

Solution 3

What you want to do - implementing a stop() method inside a Runnable - may actually introduce some confusion in the structure of your code. Why? A Runnable object is, by design, something which holds the code that has to run. But adding a stop() method would go beyond the sole responsibility of a Runnable object: that is, you will make it able to control the execution of your code. That should be avoided.

Here is a hint: there is no start() method in Runnable. Indeed, there is one in the Thread class, and the Runnable interface has been introduced in the JDK to reduce coupling between the "runnable" code and the object which controls its execution (an instance of Thread).

My question is: why aren't you satisified with the future.cancel()? Could you please add some precisions in your design requirements?

OTHER TIPS

            public class MyRunnable implements Runnable {

                private Thread currentThread;

                @Override
                public void run() {
                    currentThread = Thread.currentThread();
                    // Do here something interruptible
                }

                public void interrupt() {
                    if (currentThread != null)
                        currentThread.interrupt();
                }
            }

But as it has been said, it's bad architecture since you're mixing responsibilities of WHAT is being done (Runnable) with HOW it's being done (execution)

You can create your own class the implements Runnable and also another interface:

public interface StoppableRunnable extends Runnable {
    public void stop();
}

And use this type of Runnable which is guaranteed to have a stop() method which you can call.

Example of use:

public MyRunnable implements StoppableRunnable {

    private volatile boolean stopped = false;

    public void run() {
       while(!stopped) { // Do something.... }
    }

    public void stop() {
        stopped = true;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top