ฉันมีรหัสต่อไปนี้:
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
ในขณะที่งานไม่เคยพิมพ์ข้อความเลย อย่างน้อยนี่คือสิ่งที่เกิดขึ้นเมื่อฉันเริ่มจากคอนโซล
เมื่อฉันเริ่มต้นจากแอปพลิเคชัน GUI ด้วย TextArea ที่เอาต์พุตถูกเปลี่ยนเส้นทางไป นั่นไม่เป็นเช่นนั้น วิธีการหลักจะพิมพ์ The task has been cancelled
แต่งานก็พิมพ์ I should never be able to print this
ด้วย
นี่กำลังทำให้ฉันเป็นบ้า จากสิ่งที่ฉันเข้าใจ งานควรได้รับคำสั่ง cancel
ในขณะที่ใช้วิธี Thread.sleep(5000)
ซึ่งจะทำให้เกิดข้อยกเว้นที่ตามมา และทำให้เธรดส่งคืน แต่มันไม่เกิดขึ้นแต่หลักคิดว่าถูกยกเลิกแล้ว เหมือนกับว่าเมธอด cancel
ถูกละเลยโดยงานโดยสิ้นเชิง
ฉันได้ลองทุกอย่างที่คิดได้แล้ว โดยตรวจสอบค่าที่ส่งคืนเป็น cancel
ทำให้งานรอนานขึ้นโดยใช้ Thread.currentThread().isInterrupted()
แต่ก็ไม่มีอะไรทำงาน
ฉันรู้สึกเหมือนขาดบางสิ่งที่เรียบง่ายจริงๆ แต่ฉันไม่สามารถค้นหาว่ามันคืออะไร มีความคิดอะไรบ้าง?
ในกรณีที่ใครคิดว่าอาจเป็นอะไรบางอย่างในแอปพลิเคชัน GUI นี่คือวิธีที่เริ่มโปรแกรม:
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();
}
}
}