使用中断方法

时间:2013-08-06 13:35:12

标签: java multithreading interrupted-exception

public class TwoThreads {
        private static Object resource = new Object();

        private static void delay(long n) {
            try 
            { 
                Thread.sleep(n);
            }
            catch (Exception e)
            { 

                e.printStackTrace();
            }
        }

        public static void main(String[] args) {
            System.out.print("StartMain ");
            new Thread1().start();
            delay(1000);                       //dealay 1
            Thread t2 = new Thread2();
            t2.start();   
            delay(1000);                      // delay 2    
            t2.interrupt();                   //step 7
            delay(1000);                      //delay 3
            System.out.print("EndMain ");
        }

        static class Thread1 extends Thread {
            public void run() {
                synchronized (resource) {
                    System.out.print("Startl ");
                    delay(6000);
                    System.out.print("End1 ");
                }
            }
        }

        static class Thread2 extends Thread {
            public void run() {
                synchronized (resource) {
                    System.out.print("Start2 ");
                    delay(2000);
                    System.out.print("End2 ");
                }
            }
        }
    }

在第7步(正如我已标记的那样),主线程在线程interrupt()上调用t2,但是当它等待获取资源上的锁时,它不会抛出任何异常。之后,主线程在等待1000 ns后打印“End Main”。换句话说,主线程已经完成了它的任务,那么是什么再次触发t2.interrupt()因为它之后抛出异常?

3 个答案:

答案 0 :(得分:3)

以下是您的程序如何运行,时间戳:

0000 StartMain 
0000 Startl 
3000 EndMain 
6000 End1 
6000 Start2 
6000 End2 

为什么(括号中的时间戳)?

  • [0000] main启动Thread1,获取锁定并休眠6秒
  • [1000] main启动Thread2,它无法获取Thread1持有的锁定6秒
  • [2000]主要中断Thread2将其中断标志设置为true,但是Thread2正在等待锁定并且没有对它做任何事情
  • [3000]主要目的
  • [6000] Thread1完成睡眠并释放锁
  • [6000] Thread2可以获取它并开始进入睡眠状态(其中断的标志仍然开启)
  • [6000]睡眠检测到Thread2已被中断并立即抛出异常
  • [6000] Thread2完成,允许JVM退出

答案 1 :(得分:1)

您需要ReentrantLock

public class TwoThreads {
  private static Lock lock = new ReentrantLock();

  private static void delay(long n) {
    try {
      Thread.sleep(n);
    } catch (Exception e) {

      e.printStackTrace();
    }
  }

  public static void main(String[] args) {
    System.out.print("StartMain ");
    new Thread1().start();
    delay(1000);                       //dealay 1
    Thread t2 = new Thread2();
    t2.start();
    delay(1000);                      // delay 2    
    t2.interrupt();                   //step 7
    delay(1000);                      //delay 3
    System.out.print("EndMain ");
  }

  static class Thread1 extends Thread {
    public void run() {
      try {
        lock.lockInterruptibly();
        try {
          System.out.print("Startl ");
          delay(6000);
          System.out.print("End1 ");
        } finally {
          lock.unlock();
        }
      } catch (InterruptedException ex) {
        // Interrupted.
      }
    }

  }

  static class Thread2 extends Thread {
    public void run() {
      try {
        lock.lockInterruptibly();
        try {
          System.out.print("Start2 ");
          delay(2000);
          System.out.print("End2 ");
        } finally {
          lock.unlock();
        }
      } catch (InterruptedException ex) {
        // Interrupted.
      }
    }

  }
}

打印:

StartMain Startl EndMain End1

答案 2 :(得分:0)

这是因为当主线程关闭时,JVM会杀死你的线程。