views:

181

answers:

3

I am using a ThreadPool via ExecutorService. By calling shutDownNow() it interrupts all running threads in the pool. When this happens I want these threads to give up their resources (socket and db connections) and simply die, but without continuing to run anymore logic, eg: inserting anything into the DB. What is the simplest way to achieve this? Bellow is some sample code:

edit: forgot to mention that all my connections are released via finally. I just need to make sure that reaching that doesn't invoke various DB inserts in a reliable way.

public void threadTest() {
    Thread t = new Thread(new Runnable() {

            public void run() {
                try {
                    Thread.sleep(999999);
                } catch (InterruptedException e) {
                    //invoke thread suicide logic here
                }
            }
        });
    t.start();

    t.interrupt();
    try {
        Thread.sleep(4000);
    } catch (InterruptedException e) {
    }
}
+2  A: 

The canonical way to do this, in my opinion, involves never catching the InterruptedException at all.

You should always be releasing your resources in a finally block anyway, regardless of this issue - so let's assume that you are. In this case, all you need to do is let the InterruptedException bubble up to the top level (i.e. declare it in the throws clause for all of your methods) and voila!

Some may baulk at adding a checked exception to all of the methods. However, this is conceptually correct - a method declared to throw InterruptedException is signifying that it is a blocking method. Ordinarily, only low-level methods would implement this, as higher-level methods are seldom definitively going to involve blocking (i.e. one could come up with a plausible alternative implementation/defer to an alternative dependency that did not require it).

The really questionable thing is that you want your code to "just stop" like this. You don't really have the context to do such a thing unconditionally from a thread manager, the code running in the threads needs to co-operate with your efforts. So letting the interrupted exception bubble is one approach; another could be to catch this exception relatively low down and set a boolean stop flag which you poll in the higher-level code.

In any case, the question here is solely around how to get higher-level code to know that it should terminate in this case. If you're closing resources in finally blocks, as you should, then you know that they will always be released appropriately regardless of anything else.

Andrzej Doyle
Sounds reasonable, but I would have to pretty much have to declare every method in my project as `throws InterruptedException` wouldn't I?
Zombies
Unless you catch it at a lower level and rethrow some unchecked exception instead.
Maurice Perry
It's a shame that InterruptedException and RemoteException are checked exceptions (IMHO that is)
Maurice Perry
True, but I think this is just another specific case of the general checked-vs-unchecked debate. At least in this case `throws InterruptedException` means "this is a blocking operation" which is kind of useful, whereas often throws clauses don't *really* tell you anything about the method.
Andrzej Doyle
A: 

When the thread completes its run method, it will automatically die. So, in effect, do nothing:

public void threadTest() {
    Thread t = new Thread(new Runnable() {

            public void run() {
                try {
                    Thread.sleep(999999);
                } catch (InterruptedException e) {
                    //invoke thread suicide logic here
                    // Do nothing so the thread will die
                }
            }
        });
    t.start();

    t.interrupt();
    try {
        Thread.sleep(4000);
    } catch (InterruptedException e) {
    }
}

The thread will be freed from memory when threadTest() ends because the thread variable will no longer be referenced.

Marcus Adams
A: 

Please note that calling t.interrupt() and letting InterruptedException be thrown will not help in case of non-interruptable blockin(e.g. for threads waiting for monitor to be released or waiting for IO operation).

In these cases, you'll have to use explicit java.util.concurrent.locks.Lock (which is interruptable) instead of synchronized blocks and java.nio instead of java.io

diy