Java Thread.stop()与Thread.interrupt()的区别

20

我有以下代码:

renderThread = new Thread(new Runnable() {

    @Override
    public void run() {
        for (int i = 0; i < 10000000; i++) {
            System.out.println("Number: " + i);
        }
    }
});

renderThread.start();

try {
    Thread.sleep(100);
} catch (InterruptedException ex) {
    ex.printStackTrace();
}

renderThread.interrupt(); //It should stop, but it does not stop.

renderThread.interrupt()方法不会中断线程,它将继续运行。如果我用.stop()替换renderThread.interrupt(),则线程将停止。但是,.stop()已被弃用。 那么,如果stop已被弃用且interrupt无法工作,停止线程的正确方法是什么?


2
你为什么认为调用 interrupt停止 线程呢? - Sotirios Delimanolis
1
可能是 如何正确地停止 Java 中的线程 的重复问题。 - Mike M
7
因为在口语中,“打断某事”和“停止某事”是同义词。我并不是说这就是它的实际作用(而且文档是开始澄清这种假设的好地方),但名称具有含义。 - user2864740
6个回答

27

当您调用interrupt()时,它会触发一个布尔标志,告诉run函数它应该停止。这就是为什么我通常会像这样编写我的run函数。

void run()
{
    while(!Thread.interrupted())
    {
        //Do something
    }
}

仅仅因为调用interrupt并不意味着线程会立即或根本停止。这取决于run函数中的内容。


这意味着,当中断事件发生并且代码到达run()的结尾时,线程会自动终止存在吗? - Ágota Horváth
1
是的。据我所知,线程应该只在运行结束时停止。中断运行只是让它知道应尽快退出。调用stop()的问题在于,如果run()需要进行一些清理工作,比如关闭流,则这些工作将无法完成。 - chasep255
2
我认为这个解决方案无法解决这里的问题。当renderThread执行任务时,它没有机会检查Thread.interrupted()。 - Jimmy
如果你的线程中有 sleep 方法,那么你就需要在这个线程中调用 try...catch (InterruptedException) 中的 interrupt 方法。https://stackoverflow.com/a/36258705/7767664 - user924

6
为什么你不应该使用Thread.stop()?Doug Lea最近提到,Java 8将成为第一个取消实现该方法的Java版本。他对此发表了评论:但你确实知道!从JDK8开始,Thread.stop已经被彻底删除。它是第一个被取消实现的弃用方法。现在它只会抛出UnsupportedOperationException异常。

http://cs.oswego.edu/pipermail/concurrency-interest/2013-December/012028.html


5

3

renderThread.interrupt()不会中断线程,它会继续运行。

  • 如果线程正在执行并调用了interrupt(),则其中断状态将被设置。
  • 如果此线程在调用Object类的wait方法或此类的Thread.joinThread.sleep方法时被阻塞,则其中断状态将被清除,并且它将接收到一个InterruptedException异常。

例如:

Thread t = new Thread()
      {
          public void run()
          {
              try {
                  for(int i=0; i<10000;i++)
                      System.out.println("Is interrupTed? "+this.isInterrupted());

                  Thread.sleep(200);
              } catch (InterruptedException ex) {
                  Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
              }

          }
      };
      t.start();
      t.interrupt();
    }

上面的代码中,我使用了一个for循环来拦截中断标志,使用isInterrupted()函数并将其打印出来。当调用t.interrupt()时,isInterrupted()将返回true,您将在控制台中看到这一点。一旦它达到Thread.sleep(miliTime),您将看到捕获的InterruptedException,就像上面所述的那样。
停止线程:
如果对其调用了interrupt(),则可以利用此isInterrupted()标志检查并从执行中返回:
例如:
Thread t = new Thread()
      {
          public void run()
          {
              long executeTime = System.currentTimeMillis() ;
              int i = 0;    
              for(; i<10000 && !this.isInterrupted();i++)
                      System.out.println("Is interrupted? "+this.isInterrupted());

               System.out.println("Was Interrupted? "+this.isInterrupted()
                                  +" after cycle: "+ i);
               System.out.println("Time it gets Executed: "
                                  +(System.currentTimeMillis() - executeTime+" ms"));

          }
      };
      t.start();
        try {
            Thread.sleep(200);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
      t.interrupt();

在运行上述代码时:我在静态main函数中使用200将主线程置于休眠状态,以便启动的线程t有一定的运行时间。然后我对它调用了t.interrupt(),这会导致for循环停止并打印如下输出:
Was Interrupted? true after cycle: 1477
Time it gets Executed: 258 ms

这说明在main函数中,在调用t.interrupt();之前,for循环迭代了1148次。
请阅读Thread.interrupt()函数的文档以获取更多详细信息。

3
只需在catch块中添加以下语句,即可中断当前线程或终止线程的运行进程:
try
{
   Thread.sleep(4000);
   System.out.println("VAS CONSULTING")
}
catch(InterruptedException e)
{
   //Stop printing out VAS CONSULTING
   return;  /*This will terminate the thread*/
}

如果在run方法中未使用不会抛出Interrupted Exception的方法,则可以这样处理线程中断或终止线程。

@Override
public void run()
{

   System.out.println("VAS CONSULTING");
   if(Thread.Interrupted())
   {
     doSomethingElse();//process something else within the thread
    return; //Terminates the current Thread
   }

}

我希望这可以帮助您或其他人。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接