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
    }

}

}

有帮助吗?

解决方案

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()

其他提示

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top