看 Thinking in java 看到多线程,多一句话特别奇怪,打印如下当一个线程被中断,在异常中,isInterrupted() 返回的是false.我就觉得很奇怪,不是被 interrupted() 了么?? 为什么返回的不是 true 呢??
如果不是 interrupted 状态,那是什么状态?? 死亡了?
写了测试代码如下,望解答……谢谢!
public class Test extends Thread{

public Test()
{
super("Test-Thread");
start();
}
public void run()
{
System.out.println(this);
}

public static void main(String args[])
{
Test t=new Test();
try{
sleep(10);
t.interrupt();
}catch(InterruptedException e)
{
e.printStackTrace();
}finally{
System.out.println(t.isInterrupted());
}

}}

解决方案 »

  1.   

    我来回答的吧
    关于Thread.interrupt(); 的方法是比较特殊的,这个方法的意思是在多线程阻塞的情况下抛出异常InterruptedException
    用于中断线程,(否则线程不就一直阻塞挂死不能运行代码了?那还得了)isInterrupted() 这个方法是判断线程是否被中断的标志(注意这个标志和线程是否被中断无关的。稍候解释)
    这个标记在interrupt被调用时会是TRUE,但线程不会中断,在声明一次,线程不会中断。。
    线程何时中断,只有阻塞的时候才会根据这个判断进行中断并抛出InterruptedException首先 “阻塞”可能是IO阻塞,或者是网络阻塞,这种情况的阻塞使用interrupt是无效的。外部原因
    只有一种阻塞才有效(我个人所知道的)就是sleep方法所以你的代码写的不正确,应该是这样的。public class Test extends Thread{    public Test() 
       { 
       super("Test-Thread"); 
       // 初始化后启动线程
       start(); 
       }    public void run() 
      { 
        while(true)
        {
           System.out.println("我正在运行"); 
          try{ 
             // sleep放在线程run内部,你在main里调用的sleep是针对main主线程的。无任何意义
              // 只有中断才可以用interrupt方法抛出异常进行结束  
               sleep(10); 
             }catch(InterruptedException e) 
             { 
               e.printStackTrace(); //打印异常
                 break;//借助异常跳出线程死循环
             }
             finally{ 
               System.out.println(t.isInterrupted()); 
             } 
        }
      }    public static void main(String args[]) 
       { 
         Test t=new Test(); 
         // 线程通过初始化自动启动后面调用
         t.interrupt();
        } 
    }
    就是这样的。THINK IN JAVA里描述的相当详细的说
      

  2.   

    你的程序有点问题,t定义在main里面,在finally里无法访问
      

  3.   

    答:
    1)"当一个线程被中断,在异常中",这句话很重要,在权威的JDK API中对interrupt()有重要的叙述:(API中每一句话,程序员都要仔细注意):如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。 这说明:1)当在InterruptedException时,中断状态将被清除
    2)由于:isInterrupted() 是用于测试中断状态标记的,而该中断状态已被清除,故:
    isInterrupted() 返回的是false.为加深印象:请楼主叙述 interrupt(),interrupted(),isInterrupted()三者间的联系与区别.
      

  4.   


    不好意思。这里我疏忽了一下,应该这样。复制粘贴是麻烦
    public class Test extends Thread{    public Test() 
       { 
       super("Test-Thread"); 
       // 初始化后启动线程
       start(); 
       }    public void run() 
      { 
        while(true)
        {
           System.out.println("我正在运行"); 
          try{ 
             // sleep放在线程run内部,你在main里调用的sleep是针对main主线程的。无任何意义
              // 只有中断才可以用interrupt方法抛出异常进行结束  
               sleep(10); 
             }catch(InterruptedException e) 
             { 
               e.printStackTrace(); //打印异常
                 break;//借助异常跳出线程死循环
             }
             finally{ 
               System.out.println(this.isInterrupted()); 
             } 
        }
      }    public static void main(String args[]) 
       { 
         Test t=new Test(); 
         // 线程通过初始化自动启动后面调用
         t.interrupt();
        } 
    }
      

  5.   

    interrupt(),interrupted(),isInterrupted() 这3个东西就我来看就是提供给线程的一套工具。
    可以的话还是通过你自己的共享变量进行控制中断线程是比较妥当的。帮助楼主加深下
    interrupt
    public void interrupt()
    Interrupts this thread. 
    Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown. If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException. If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException. If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked. If none of the previous conditions hold then this thread's interrupt status will be set. 
    Throws: 
    SecurityException - if the current thread cannot modify this thread--------------------------------------------------------------------------------interrupted
    public static boolean interrupted()
    Tests whether the current thread has been interrupted. The interrupted status of the thread is cleared by this method. In other words, if this method were to be called twice in succession, the second call would return false (unless the current thread were interrupted again, after the first call had cleared its interrupted status and before the second call had examined it). Returns:
    true if the current thread has been interrupted; false otherwise.
    See Also:
    isInterrupted()
    isInterrupted
    public boolean isInterrupted()
    Tests whether this thread has been interrupted. The interrupted status of the thread is unaffected by this method. Returns:
    true if this thread has been interrupted; false otherwise.
    See Also:
    interrupted()多看英文有好处
      

  6.   

    LZ的程序并没有出现InterruptedException异常,所以并没有所谓的中断状态的清除。
    大家看看
    isInterrupted
    public boolean isInterrupted()
    测试线程是否已经中断。线程的中断状态 不受该方法的影响。 

    线程中断被忽略,因为在中断时不处于活动状态的线程将由此返回 false 的方法反映出来。 
    返回:
    如果该线程已经中断,则返回 true;否则返回 false。
    另请参见:
    interrupted()
      

  7.   

    答:ZiSheng兄弟:我们回答的不是楼主的程序问题,而是楼主这个贴子的核心问题:看 Thinking in java 看到多线程,多一句话特别奇怪,打印如下 当一个线程被中断,在异常中,isInterrupted() 返回的是false. 我就觉得很奇怪,不是被 interrupted() 了么?? 为什么返回的不是 true 呢?? 与楼主自己写的程序正确与否无关的.
      

  8.   


    问题的关键所在就在于当你调用t.interrupt(); 这句话之前,你的t已经死了,所以你再去中断他没有任何意义。
    public class Test extends Thread{  public Test() 

    super("Test-Thread"); 
    start(); 

    public void run() 

    System.out.println(this); 
    }  public static void main(String args[]) 

    Test t=new Test(); 
    try{ 
    sleep(10); 
    System.out.println(t.isInterrupted()); 
    t.interrupt(); 
    }catch(InterruptedException e) 

    e.printStackTrace(); 
    }finally{ 
    System.out.println(t.isInterrupted()); 
    }  } 在中断之前,你测试下看看,我添加了一句。
      

  9.   

    云上飞翔兄:这个不正是你在5楼解释的情况吗?,中断状态被清除,isInterrupted返回false。
    具体为何是false,我也不明白:(
      

  10.   

    错误倒是没有,就是看起来别扭点。
    看这句话:
    线程中断被忽略,因为在中断时不处于活动状态的线程将由此返回 false 的方法反映出来。 
    意思是说当你去中断一个不处于活动状态的线程的时候(你调用interrupt();),对该线程的中断忽略,
    就是你的中断没有起到作用,最后以返回false反映出来。 
      

  11.   

    答:兄弟上述的话,我认为是很正确的.这正是false的由来.
    我想说的是,中断一个不处于活动状态的线程时,这个"不处于活动状态"其实是线程的两种状态:1)创建态(创建了线程,但还没有调用start())  2)死亡态    
    在"阻塞"状态下,还是interrupt()是起作用的(当然处于 运行态  ,也是有效的.).