chzbrgla
chzbrgla

Reputation: 5188

Stopping an infinite loop Runnable run from ThreadPool

I have a Runnable implementing class which will be run from a Executors.newFixedThreadPool Inside the Runnable, I have an infinite-loop running which listens on an UDP Port for incoming data.

I want to gracefully end the Runnable in order to close said UDP Ports.

How can I achieve this? When extending Thread directly, I have access to interrupt() and isInterupted() etc. on which I can base my infinite loop.

In the Runnable implementing class however, I want to to do something like

@Override
public void run() {
    while (active) {

    }
}

and have

private boolean active = true;

How can I set active = false when the ThreadPool is terminated?

Upvotes: 2

Views: 6510

Answers (4)

Philipp Reichart
Philipp Reichart

Reputation: 20961

You can access the interrupt flag of the current thread using the static method Thread.interrupted(), e.g. instead of your active flag use:

public void run() {
    try {
        // open your ports
        while (!Thread.interrupted()) {
            // do stuff
        }
    } finally {
        // close your ports in finally-block
        // so they get closed even on exceptions
    }
}

And when you want to shutdown your ExecutorService, call shutdownNow() on it. This will interrupt() any running worker threads and have your Runnable break out of its loop.

Upvotes: 8

ZenMaster
ZenMaster

Reputation: 12742

I would suggest to not use 'Runnable', rather override 'FutureTask' and implement it's 'done' and 'cancel' (if necessary) methods - where you can make all the necessary clean up operations.

EDIT:

forgot `cancel' method.

Upvotes: 1

ratchet freak
ratchet freak

Reputation: 48196

if you get a Future when you submit the task you can cancel(boolean) the future, if you pass true the thread the task is running on will be interrupted

@Override
public void run() {
    try{
        while (!Thread.interrupted()) {


             if(Thread.interrupted())return;//to quit from the middle of the loop
        }
    }finally{
        //cleanup
    }
}

note that you'll have to reset the interrupted flag with Thread.currentThread().interrupt(); each time you get a thrown InterruptedException

Upvotes: 2

Ajay George
Ajay George

Reputation: 11875

you can use this

while (!executor.isShutdown) {
//do your job
}

or use an AtomicBoolean in the while loop. (preferable over volatile)

This flag can be set if you want to stop processing manually, from some method like stopProcessing()

Upvotes: 1

Related Questions