【问题标题】:Does calling Thread.interrupt() before a Thread.join() cause the join() to throw an InterruptedException immediately?在 Thread.join() 之前调用 Thread.interrupt() 会导致 join() 立即抛出 InterruptedException 吗?
【发布时间】:2012-05-24 20:05:08
【问题描述】:

基本上,问题的标题是什么。

Thread t = new Thread(someRunnable);
t.start();
t.interrupt();
t.join(); //does an InterruptedException get thrown immediately here?

从我自己的测试来看,似乎是这样,但只是想确定一下。我猜Thread.join() 在执行“等待”例程之前会检查线程的interrupted 状态?

【问题讨论】:

  • 不,Thread.join() 只关心当前线程的中断。

标签: java multithreading concurrency interrupt interrupted-exception


【解决方案1】:

interrupt() 将中断引用线程的执行,如果它受到sleep()wait()join() 的影响。

  1. 由于没有在 main 上调用 sleep /join /wait,这只会更新 interrupted 标志。
  2. 验证语句 1
  3. t1.join() 暂停 MAIN thread 的执行并允许 t1 在 MAIN thread 继续之前执行。但是,似乎 main 在内部检查 Thread.currentThread().isIntercepted() 并通过引发异常来处理。
  4. 验证语句 3
  5. 验证语句 3,并且由于引发了异常,intercepted 标志被设置回 false

示例代码:

        t1.start();
        System.out.println(Thread.currentThread().getName()+" isInterrupted(): "+Thread.currentThread().isInterrupted());
        try {
            Thread.currentThread().interrupt(); // -- 1
            System.out.println(Thread.currentThread().getName()+" isInterrupted(): "+Thread.currentThread().isInterrupted()); // -- 2
            t1.join(); // -- 3
            System.out.println("This is never called as exception is raised"); // -- 4
        }catch(InterruptedException ex){
            System.out.println(Thread.currentThread().getName()+" isInterrupted(): "+Thread.currentThread().isInterrupted()); -- 5
        }
        System.out.println("Main continues");

输出:

main isInterrupted(): false
Thread-0: 0
main isInterrupted(): true
main isInterrupted(): false
Main continues
Thread-0: 1
Thread-0: 2
Thread-0: 3

以上电话来自main()

我希望这将有助于更好地理解?

【讨论】:

    【解决方案2】:

    在 Thread.join() 之前调用 Thread.interrupt() 会导致 join() 立即抛出 InterruptedException 吗?

    不,它不会抛出。只有当调用join() 方法的当前 线程被中断时,join() 才会抛出InterruptedExceptiont.interrupt() 正在中断您刚刚启动的线程,而 t.join() 只会在正在执行连接的线程(可能是主线程?)本身被中断时抛出 InterruptedException

     Thread t = new Thread(someRunnable);
     t.start();
     t.interrupt();
     t.join();  // will _not_ throw unless this thread calling join gets interrupted
    

    同样重要的是要意识到中断线程不会取消它并且join() 不像Future,因为它会返回线程抛出的异常。

    当您中断一个线程时,该线程对sleep()wait()join() 和其他可中断方法进行的任何调用都会抛出InterruptedException。如果没有调用这些方法,那么线程将继续运行。如果线程确实抛出 InterruptedException 以响应被中断然后退出,除非您使用 t.setDefaultUncaughtExceptionHandler(handler),否则该异常将丢失。

    在您的情况下,如果线程因为返回而被中断并完成,那么连接将完成——它不会抛出异常。正确处理中断的常用线程代码如下:

     public void run() {
        try {
           Thread.sleep(10000);
        } catch (InterruptedException e) {
           // a good pattern is to re-interrupt the thread when you catch
           Thread.currentThread().interrupt();
           // another good pattern is to make sure that if you _are_ interrupted,
           // that you stop the thread
           return;
        }
     }
    

    【讨论】:

      【解决方案3】:

      interrupt() 会中断您中断的线程,而不是执行中断的线程。

      c.f.

      Thread.currentThread().interrupt();
      t.join(); // will throw InterruptedException 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多