我想立即停止正在运行的线程。这是我的代码:
A类:
public class A() {
public void methodA() {
For (int n=0;n<100;n++) {
//Do something recursive
}
//Another for-loop here
//A resursive method here
//Another for-loop here
finishingMethod();
}
}
B组:
public class B() {
public void runEverything() {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
A a = new A();
a.methodA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
我的问题是我需要能够在线程完成之前在B类中停止线程。我已经尝试过interrupt()方法,但这并没有阻止我的线程。我也听说过使用共享变量作为一个信号来阻止我的线程,但我认为在我的进程中使用长递归和for循环,共享变量将不会有效。
有什么想法吗? 提前谢谢。
答案 0 :(得分:13)
Thread.interrupt
不会停止你的线程(除非它处于睡眠状态,在这种情况下会抛出InterruptedException
)。中断基本上会向线程发送一条消息,指示它已被中断,但它不会导致线程立即停止。
当您进行长循环操作时,使用标志来检查线程是否已被取消是一种标准方法。您可以修改methodA
以添加该标志,例如:
// this is a new instance variable in `A`
private volatile boolean cancelled = false;
// this is part of your methodA
for (int n=0;n<100;n++) {
if ( cancelled ) {
return; // or handle this however you want
}
}
// each of your other loops should work the same way
然后可以添加取消方法来设置该标志
public void cancel() {
cancelled = true;
}
如果有人在runEverything
上拨打B
,B
就可以在cancel
上拨打A
(您必须提取A
变量使得B
即使在调用runEverything
后也会引用它。
答案 1 :(得分:2)
我认为你应该坚持使用Thread.interrupt()
。但是,要使其工作,您需要做的是更改methodA
代码以执行以下操作:
public void methodA() throws InterruptedException {
for (int n=0; n < 100; n++) {
if (Thread.interrupted) {
throw new InterruptedException();
}
//Do something recursive
}
// and so on.
}
这相当于声明并使用你自己的“kill switch”变量,但是:
interrupted
状态和interrupted
州。现在确实有很多代码错误处理 InterruptedException
;例如通过挤压它。 (处理InterruptedException
的正确方法是允许它传播,或者调用Thread.interrupt()
再次设置标志。)然而,反面是相同的代码不会意识到你的杀戮开关。无论如何你都有问题。
答案 2 :(得分:1)
您可以检查运行标志的状态,作为循环或递归的一部分。如果有一个kill信号(即run flag设置为false),只需返回(在你需要进行任何清理之后)。
答案 3 :(得分:0)
还有其他一些可能的方法:
1)不要停止它 - 用“中断”标志发出信号停止,将其优先级设置为最低可能,然后“孤立”线程及其正在处理的任何数据对象。如果您需要再次执行此线程所执行的操作,请再创建一个。
2)将其正在处理的数据空出,损坏,重命名,关闭或以其他方式销毁以强制线程进行segfault / AV或以其他方式除外。线程可以捕获throw并检查Interrupted标志。
没有保证,按原样出售......
答案 4 :(得分:0)
从主线程开始letvsay someTask()被调用,并且t1.interrput被调用..
t1.interrupt();
}
private static Runnable someTask(){
return ()->{
while(running){
try {
if(Thread.interrupted()){
throw new InterruptedException( );
}
// System.out.println(i + " the current thread is "+Thread.currentThread().getName());
// Thread.sleep( 2000 );
} catch (Exception e) {
System.out.println(" the thread is interrputed "+Thread.currentThread().getName());
e.printStackTrace();
break;
}
}
o / P:
java.lang.InterruptedException
at com.barcap.test.Threading.interrupt.ThreadT2Interrupt.lambda$someTask$0(ThreadT2Interrupt.java:32)
at java.lang.Thread.run(Thread.java:748)
the thread is interrputed Thread-0
仅t1.interuuption
是不够的。这需要检查子线程中Thread.interrupted()的状态。