ExecutorService incorrectly calls interrupt ()

I created an ExecutorService to manage all of my separate threads that are handling the socket connection. I've tried the interrupt method on each of these threads to close the socket when the thread is interrupted, if the socket is currently in non-interruptible mode (e.g. socketserver.accept ()).

If I manually trigger an interrupt on my threads when the application exits, everything closes as expected. However, if I use my ExecutorService and run shutdownNow, it doesn't seem to call the overridden interrupt method at all.

Why isn't it calling my overridden method?

+3


source to share


1 answer


I had the same problem and found a solution using thread pool. Below is a description and simplified code.

1) Created my own thread class that overrides interrupt (), also calls the close () method, which is configured using the setter and the Closeable interface that I created. Override interrupt () to call the close method, if configured.

public class CloseableThread extends Thread {
    private Closeable mCloseable = null;

    public interface Closeable {
        void close();
    }

    // Constructors deleted

    public void interrupt() {
        super.interrupt();
        if (mCloseable != null) {
            mCloseable.close();
        }
    }

    public void setCloseable(Closeable closeable) {
        mCloseable = closeable;
    }
}

      



2) Created my own pool class that extends ThreadPool, which has a factory for my thread to close and overrides beforeExecute () to set the closure.

public class CloseableThreadPoolExecutor extends ThreadPoolExecutor {
    static class CloseableThreadFactory implements ThreadFactory {
        public Thread newThread(Runnable r) {
            return (Thread) new CloseableThread(r);
        }
    }

    // Constructors deleted

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        super.beforeExecute(t, r);

        if (t instanceof CloseableThread && r instanceof Closeable) {
            ((CloseableThread) t).setCloseable((Closeable) r);
        }
    }
}

      

3) Make sure any task using sockets implements Closeable and the close () method causes the socket to close. Be sure to clean up the socket exception that will be thrown when you close this path.

0


source







All Articles