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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With