Question

I need MyThread.interrupt() to be called when I cancel currently executing task. Why isn't itpublic class Main {

public static void main(String[] args) {
    ExecutorService executor = Executors.newFixedThreadPool(10);
    List<MyThread> threads = new ArrayList<Main.MyThread>();

    List<Future> futureList = new ArrayList<Future>();
    for (int i = 0; i < 30; i++) {
        MyThread myThread = new MyThread(i);
        futureList.add(executor.submit(myThread));
        threads.add(myThread);
    }
    for (Future future : futureList) {
        if (future != null) {
            future.cancel(true);
        }
    }

    // Calling interrupt directly. It works
    for (MyThread myThread : threads) {
        myThread.interrupt();
    }
    shutdownAndAwaitTermination(executor);

}

static void shutdownAndAwaitTermination(ExecutorService pool) {
    pool.shutdown(); // Disable new tasks from being submitted
    try {
        // Wait a while for existing tasks to terminate
        if (!pool.awaitTermination(10, TimeUnit.SECONDS)) {
            pool.shutdownNow(); // Cancel currently executing tasks
            // Wait a while for tasks to respond to being cancelled
            if (!pool.awaitTermination(10, TimeUnit.SECONDS)) System.err.println("Pool did not terminate");
            else System.out.println("Maybe OK");
        } else {
            System.out.println("OK");
        }
    } catch (InterruptedException ie) {
        // (Re-)Cancel if current thread also interrupted
        pool.shutdownNow();
        // Preserve interrupt status
        Thread.currentThread().interrupt();
    }
}

private static class MyThread extends Thread {

    HttpURLConnection connection;

    final int i;

    public MyThread(int i) {
        this.i = i;
    }

    @Override
    public void interrupt() {
        super.interrupt();
        if (connection != null) {
            connection.disconnect();
        }
    }

    @Override
    public void run() {
        // Initialize HttpURLConnection and upload / download data
    }

}

}

Was it helpful?

Solution

It is called, change it here and see output

...
            } catch (InterruptedException e) {
                System.out.println(i + " interrupted");
                Thread.currentThread().interrupt();
            }
...

the problem is that ThreadPoolExecutor uses its own Thread to run your task and it will interrupt this thread not yours. It makes no sense to extend Thread, implement Runnable instead. If you still to use Thread then you can call MyThread.interrupt() directly from MyThread.run()

OTHER TIPS

executor.submit(new MyThread(i)) works because MyThread extends Thread which implements Runnable.

As such, the run method is actually executed by one of the 10 threads your started in the thread pool. When cancelling the Future, the interrupt method of MyThread is not executed as it is not the executing thread but considered a Runnable. Nevertheless, The interrupt of the threads started by your pool is called.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top