Java 立即停止线程

Java 立即停止线程,java,multithreading,Java,Multithreading,我想立即停止运行的线程。这是我的密码: 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

我想立即停止运行的线程。这是我的密码:

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中的线程,甚至在线程完成之前。我尝试了interrupt()方法,但这并没有停止我的线程。我也听说过使用共享变量作为停止线程的信号,但我认为在我的过程中使用长递归和for循环,共享变量将不会有效

有什么想法吗?
提前感谢。

您可以在循环或递归过程中检查运行标志的状态。如果有终止信号(即run标志设置为false),只需返回(在您需要执行的任何清理之后)。

线程。中断将不会停止您的线程(除非它处于睡眠状态,在这种情况下,将抛出
InterruptedException
)。中断基本上会向线程发送一条消息,指示它已被中断,但不会导致线程立即停止

当执行长循环操作时,使用标志检查线程是否已取消是一种标准方法。您的
方法a
可以修改以添加该标志,例如:

// 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

然后,如果有人在
B
上调用
runearthing
B
就可以在
A
上调用
cancel
(您必须提取
A
变量,这样
B
即使在调用
运行一切
之后也可以引用它。

我认为您应该坚持使用
线程.interrupt()
。但要使其工作,您需要做的是更改
方法A
代码以执行以下操作:

public void methodA() throws InterruptedException {
    for (int n=0; n < 100; n++) {
        if (Thread.interrupted) {
             throw new InterruptedException();
        }
        //Do something recursive
    }
    // and so on.        
}
public void methodA()引发InterruptedException{
对于(int n=0;n<100;n++){
if(线程中断){
抛出新的InterruptedException();
}
//做一些递归的事情
}
//等等。
}
这相当于声明和使用您自己的“kill switch”变量,除了:

  • 许多同步API和一些I/O API关注
    中断的状态,以及
  • 一个表现良好的第三方库会注意到
    中断的状态

现在确实有很多代码错误地处理了
InterruptedException
;例如挤压它。(处理
InterruptedException
的正确方法是允许它传播,或者调用
Thread.interrupt()
再次设置标志。)然而,另一方面,相同的代码不会意识到您的终止开关。因此,无论哪种方式,您都会遇到问题。

还有一些其他可能的方法:

1) 不要停止它-用中断标志向它发出停止信号,将其优先级设置为尽可能低,并“孤立”线程及其正在处理的任何数据对象。如果需要此线程再次执行的操作,请进行另一个操作

2) 清空、损坏、重命名、关闭或以其他方式销毁正在处理的数据,以强制线程执行segfault/AV或其他方式。线程可以捕捉抛出并检查中断标志


不保证,如图所示出售…

来自主线程,假设调用了someTask(),调用了t1.interput

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:


只有
t1.interuoption
是不够的。这需要检查子线程中Thread.interrupted()的状态。

+1了解volatile。最好能解释一下为什么它很重要。volatile关键字是必需的,因为执行取消的线程与被取消的线程不同。将其标记为volatile可确保检查标志的线程将看到最新值。感谢您的回答。我为我的无知感到抱歉。但是,如果我有很多循环和递归方法,那么实现这一点的唯一方法是在所有地方添加标志检查,这是正确的吗?为了使其可取消,这可能是最简单的方法。没有办法安全地杀死线程,因此需要允许它干净地退出(如果中断线程,可以检查thread.currentThread().isInterrupted(),但interrupted经常被错误地使用,因此这并不总是可靠的)。线程中断机制是可靠的,但草率的代码经常捕获并忽略InterruptedException。杰夫·斯托雷所说的不可靠可能就是这个意思。OTOH如果目标线程在wait()或sleep()或join()中被阻塞,那么中断它会更好,因为在阻塞时没有机会检查标志。
public void methodA() throws InterruptedException {
    for (int n=0; n < 100; n++) {
        if (Thread.interrupted) {
             throw new InterruptedException();
        }
        //Do something recursive
    }
    // and so on.        
}
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;
                }
            }
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