У меня такой код:
public class Cancelling {
public static void main(String args[]) {
ToBeCancelled tbc = new ToBeCancelled();
ForkJoinPool pool = new ForkJoinPool(1);
Future<?> future = pool.submit(tbc);
try {
Thread.sleep(3000);
} catch (InterruptedException ie) {}
future.cancel(true);
if (future.isCancelled())
System.out.println("The task has been cancelled");
}
}
С классом ToBeCancelled
:
public class ToBeCancelled implements Runnable {
public void run() {
try {
Thread.sleep(5000); // should throw exception here
} catch (Exception e) {
return; // should exit
}
System.out.println("I should never be able to print this");
}
}
Основной поток должен запуститься, подождать 3 секунды, а затем отменить задачу ToBeCancelled
, используя future.cancel(true)
. Затем он должен напечатать The task has been cancelled
, в то время как задача никогда не сможет распечатать свое сообщение. По крайней мере, это то, что происходит, когда я запускаю его с консоли.
Поскольку я запускаю его из приложения с графическим интерфейсом пользователя с TextArea, куда перенаправляется вывод, это не так. Основной метод печатает The task has been cancelled
, но задача также печатает I should never be able to print this
.
Это сводит меня с ума. Насколько я понимаю, задача должна получить свою команду cancel
при использовании метода Thread.sleep(5000)
, который вызовет исключение, которое, следовательно, будет перехвачено и приведет к возврату потока. Но этого не происходит, а главное думает, что его отменили. Как будто метод cancel
полностью игнорируется задачей.
Я перепробовал все, что мог придумать, проверяя возвращаемое значение cancel
, заставляя задачу ждать дольше, используя Thread.currentThread().isInterrupted()
, но ничего не работает.
Мне кажется, что мне не хватает чего-то очень простого, но я просто не могу найти, что это такое. Любая идея?
Если кто-то думает, что это может быть что-то в приложении с графическим интерфейсом, это метод, который запускает программу:
public static void StartProgram(String name) {
try {
Method m = Class.forName(name).getDeclaredMethod("main",String[].class);
Object[] args = new Object[1];
String s[] = new String[2];
s[0] = tf1.getText();
s[1] = tf2.getText();
args[0] = s;
t = new Thread(new ProgramStarter(args, m));
t.start();
} catch (Exception e) {
e.printStackTrace();
}
}
При этом ProgramStarter
:
public class ProgramStarter implements Runnable {
private Object[] args;
private Method m;
public ProgramStarter(Object args[], Method m) {
this.args = args;
this.m = m;
}
public void run() {
try {
m.invoke(null, args);
} catch (Exception e) {
e.printStackTrace();
}
}
}