首先贴上代码public class MainTest3 { /**
 * @param args
 */
public  static Object resource = new Object();
private static long startTime= System.currentTimeMillis();

private static void delay(long n){
try{
Thread.sleep(n);
}catch(Exception e){
long timeError=System.currentTimeMillis()-startTime;
System.out.println("(error at "+timeError+") ");
}
}

public static void main(String [] args){
long timeStartMain =System.currentTimeMillis()-startTime;
System.out.println("(StartMain at "+timeStartMain+") ");
new Thread1().start();
delay(1000);
Thread t2 =new Thread2();
t2.start();
delay(1000);
t2.interrupt();
delay(1000);
long timeEndMain=System.currentTimeMillis()-startTime;
System.out.println("(EndMain at "+timeEndMain+") ");
}
static class Thread1 extends Thread{
public void run(){
synchronized(resource){
long timeStart1=System.currentTimeMillis()-startTime;
System.out.println("(Start1 at "+timeStart1+") ");
delay(6000);
long timeEnd1=System.currentTimeMillis()-startTime;
System.out.println("(End1 at "+timeEnd1+") ");
}
}
}
static class Thread2 extends Thread{
public void run(){
synchronized(resource){
long timeStart2=System.currentTimeMillis()-startTime;
System.out.println("(Start2 at "+timeStart2+") ");
delay(2000);
long timeEnd2=System.currentTimeMillis()-startTime;
System.out.println("(End2 at "+timeEnd2+") ");
}
}
}
}
以下是结果:
也就是以毫秒为单位,各个时间点发生的事情列表(StartMain at 0) 
(Start1 at 0) 
(EndMain at 3000) 
(End1 at 6000) 
(Start2 at 6000) 
(error at 6000) 
(End2 at 6000) 我有2个疑问,,我看了半天书也没明白,所以才设计这样的一个程序来自己运行一下问题1:红色部分显示的t2.interrupt()调用前后是将t2的状态位从什么改变成什么?
      我原来认为,由于使用了同步锁Object,所以 t2.interrupt() 调用前,是处于等待锁的wait状态,,然后       t2.interrupt()调用之后,t2直接从等待区出来,并且t2获得锁,,但是事实证明我的想法是错误的。。希望大家帮我解释下。
问题2:橙色部分显示的消息,是具体对应代码的哪行时候才出来的?我的意思,这个方法抛出InterruptException的前提应该是在没自动醒来之前被“吵醒”吧,那么什么地方的代码,把t2吵醒了?

解决方案 »

  1.   

    问题1:
    t2.interrupt()是让该线程中断。通俗的说,就是强制结束线程 t2 的运行。问题2:
    interrupt()会引发InterruptException
    橙色部分显示的消息,正是t2.interrupt()执行的结果。
      

  2.   

    好像不是把,,interrupt 方法貌似只是设置中断位吧。比如一个线程
    try{
    Thread a = new Thread();
    a.sleep();
    a.interrupt();
    }catch(Exception e){}则interrupt 方法非但不是让其借宿运行,反而让其放弃暂停状态
      

  3.   

    interrupt
    public void interrupt()中断线程2楼举的例子很怪,还没start就sleep和interrupt了?
      

  4.   

    1.main调用,输出
    2.thread1调用,输出
    3.main调用结束,输出
    4.thread1调用结束,输出
    5.虽然在main调用中启动了thread2,但由于resource的同步以及sleep()不丢失任何监视器的所属权,只有当thread1放弃resource后,thread2才开始调用,输出
    6.main调用了t2.interrupt(),因为thread2未执行过,故thread2的中断状态被设置。一旦thread2进入sleep()即被打断,抛出InterruptedException进入异常处理,输出
    7.thread2调用结束,退出
    8.所有前台线程均退出后,程序结束退出
      

  5.   

    我只是打个比方。。我看API ,感觉书上说的interrupt 方法并不就是让线程中断。而是只是改变中断状态位吧。
    其实,我只是对 0楼的问题感到不明白,希望指教
      

  6.   


    想问下,,,关于第6点的说法,的确thread2从没有被执行过,那么thread2 是处于线程的哪个状态呢?t2.start()已经执行了,但是由于锁被thread1占用,因此t2仅仅是处于wait状态,而并没有被JVM 的线程调度程序调用,是吗?然后t2.interrupt 就使得他从wait态成为就绪态?是这样的么?
      

  7.   

    我其实一个关键没有理解的问题就在于对于一个仅仅有生命,但是还不在就绪队列中的线程 ,也就是thread.start()之后,thread.run()之前,这样的一个线程,一旦对它调用interrupt方法,则会发生哪些变化?包括线程的状态有哪些变化?包括是否获得对象锁?我这些不太明白
      

  8.   

    我是在网上看一些信息的
    比如 链接1
    比如 http://www.knowsky.com/369443.html其实,我也是从大家说的东西中总结出来的,我看了JAVA 编程思想,还有CORE JAVA 貌似,都没有说的太清楚。还是我理解能力有问题
      

  9.   


    错了
    首先,是resource被thread1丢弃后,thread2就从wait中恢复执行
    然后,由于其自主进入sleep,放弃了运行
    再次,先前interrupt所置的中断状态将其由休眠转入就绪
    最后,由于当前只有thread2一个线程存活,就绪转为运行
      

  10.   

    貌似有点明白了,也就是Thread2中的代码
    static class Thread2 extends Thread{
    public void run(){
    synchronized(resource){
    long timeStart2=System.currentTimeMillis()-startTime;
    System.out.println("(Start2 at "+timeStart2+") ");
    delay(2000);
    long timeEnd2=System.currentTimeMillis()-startTime;
    System.out.println("(End2 at "+timeEnd2+") ");

     
    粉红色的刚睡下去,就立刻由于thread2中的循环检测中断标志,而醒来(夸张点,就是比如设置要睡2小时的,结果刚睡下去不到5秒钟,手机就把你叫醒了),是这个意思吧??然后由于这个状态的切换,所以抛出InterruptedException,然后自动进入catch语句,也就是
    private static void delay(long n){
    try{
    Thread.sleep(n);
    }catch(Exception e){
    long timeError=System.currentTimeMillis()-startTime;
    System.out.println("(error at "+timeError+") ");

    }
    } 所以就结果输出 (error at)
    然后继续回到执行体run中,就打印出(End2 at )  是吧。正是因为刚睡就醒来了,所以,
    (End1 at 6000) 
    (Start2 at 6000) 
    (error at 6000) 
    (End2 at 6000) 
    4个标志几乎发生在同时?是吗?
      

  11.   

    YES!
    刚执行你的代码,有一次是这个结果
    (Start2 at 6000)
    (error at 6062)
    (End2 at 6062) 所以,也就是几乎同时,还是要看CPU调用的