为什么Thread.interrupt()的行为会出现这种情况?

3
这是对Java并发教程中代码的修改。
package threads;

public class SimpleThreads {
 static void threadMessage(String msg) {
  String threadName = Thread.currentThread().getName();
  System.out.format("%s: %s%n", threadName,msg);
 }
 private static class MessageLoop implements Runnable{

  @Override
  public void run() {
   // TODO Auto-generated method stub
   String[] importantInfo= {"apple","bat","chlorine","dog","egg","fog","gun"};
   try {
    for(int i=0;i<importantInfo.length;i++) {
     Thread.sleep(4000);
     threadMessage(importantInfo[i]);
    }
   }catch(InterruptedException ie) {
    threadMessage("i wasn't done");
   }
     }
 }
 /**
  * @param args
  */
 public static void main(String[] args) throws InterruptedException{
  // TODO Auto-generated method stub
  long patience = 100;
  if(args.length > 0)
   try {
    patience = Long.parseLong(args[0]) * 1000;
   }catch(NumberFormatException nfe) {
    System.err.println("argument must be a integer");
    System.exit(1);
   }
  threadMessage("starting message loop thread");
  long startTime = System.currentTimeMillis();
  Thread t = new Thread(new MessageLoop());
  t.start();

  threadMessage("waiting for messageloop thread to finish");
  while(t.isAlive()) {
   threadMessage("still waiting...");
   //t.join(1000);
   if(((System.currentTimeMillis() - startTime) > patience) && t.isAlive()) {
    threadMessage("tired of waiting");
    t.interrupt();
    //t.join();
   }
  }
  threadMessage("finally");
 }

}

这是输出结果

main: starting message loop thread
main: waiting for messageloop thread to finish
main: still waiting...
main: still waiting...
...(repeats about 100 times)
main: still waiting...
main: still waiting...
main: still waiting...
main: still waiting...
main: tired of waiting
main: still waiting...
main: tired of waiting
main: still waiting...
main: tired of waiting
main: still waiting...
main: tired of waiting
main: still waiting...
main: tired of waiting
Thread-0: i wasn't done
main: finally

我原本期望在第一个(也是唯一的) main: tired of waiting 后会看到 Thread-0: i wasn't done ,但实际上出现了 5 次 main: tired of waiting -- 这是为什么呢?

2个回答

5

Thread.Interrupt()函数只是向目标线程发送一个中断信号或异常,它不会立即终止该线程。

此外,在发送中断信号和目标线程接收和处理该信号之间可能会存在延迟;上下文切换不能保证立即发生。

您可以通过执行某种形式的阻塞操作(例如I/O或休眠)或调用Thread.yield()函数来鼓励JVM更快地进行上下文切换,但无法强制执行。


主函数:等待太久了,可能会发生N次——5只是基于虚拟机时间的任意数字。 - non sequitor
当然可以,因为上下文切换发生的时间也是(半)随意的。 - RickNZ

0

Thread.interrupt()并不会杀死或中断线程。
它只是中断一些方法,例如sleep、wait、join、在可中断通道上阻塞的I/O或阻塞的选择器。否则,它只是设置线程的中断标志,由您来测试这个标志。
如果您删除上面代码中的sleep,则中断将没有可见效果。

线程(主循环)实际上继续运行,直到系统转换为中断线程,因此可能会中断几次。中断后,您可以添加一个sleep()或yield()(如指示的join()也应该有效),以允许中断的线程运行。

    threadMessage("tired of waiting");
    t.interrupt();
    t.yield();

另请参阅中断文档


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