简体   繁体   English

Thread.interrupt() 的奇怪行为

[英]Strange behaviour with Thread.interrupt()

I was trying to understand more about Thread.interrupt(), and so I wrote the following codes.我试图更多地了解 Thread.interrupt(),因此我编写了以下代码。

public class Test {

    private Object object = new Object();

    Runnable thread1 = () -> {
        synchronized (object) {
            System.out.println(System.currentTimeMillis() + " - Thread1 inside synchronized block");
            try {
                object.wait();
                System.out.println(System.currentTimeMillis() + " - Thread1 after wait()");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(System.currentTimeMillis() + " - Thread1 ending");
        }
    };

    Runnable thread2 = () -> {
        synchronized (object) {
            System.out.println(System.currentTimeMillis() + " - Thread2 inside synchronized block");
            try {
                Thread.sleep(2000);
                System.out.println(System.currentTimeMillis() + " - Thread2 after sleep");
                object.notify();
                System.out.println(System.currentTimeMillis() + " - Thread2 after notify()");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(System.currentTimeMillis() + " - Thread2 ending");
        }
    };

    public void run() {
        Thread t1 = new Thread(thread1);
        Thread t2 = new Thread(thread2);
        t1.start();
        t2.start();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t1.interrupt();
    }

    public static void main(String[] args) {
        new Test().run();
    }

}

I couldn't understand the result.我无法理解结果。 Firstly, why is the exception stack trace not showing on the third line of the output?首先,为什么在 output 的第三行没有显示异常堆栈跟踪? The first thread was interrupted while the second thread was still sleeping, so the exception should occur before the second thread woke up.第一个线程在第二个线程仍在休眠时被中断,因此异常应该在第二个线程醒来之前发生。 Secondly, why is "Thread 1 ending" showing up before the stack trace?其次,为什么“线程 1 结束”出现在堆栈跟踪之前?

1643099950931 - Thread1 inside synchronized block
1643099950947 - Thread2 inside synchronized block
1643099952947 - Thread2 after sleep
1643099952947 - Thread2 after notify()
1643099952947 - Thread2 ending
1643099952947 - Thread1 ending
java.lang.InterruptedException
    at java.base/java.lang.Object.wait(Native Method)
    at java.base/java.lang.Object.wait(Object.java:328)
    at com.ocbc.ms.Test.lambda$new$0(Test.java:13)
    at java.base/java.lang.Thread.run(Thread.java:834)

From the documentation of Thread.wait (relevant part highlighted in bold):Thread.wait的文档中(相关部分以粗体突出显示):

Causes the current thread to wait until it is awakened, typically by being notified or interrupted , or until a certain amount of real time has elapsed.使当前线程等待直到它被唤醒,通常是通过通知中断,或者直到经过一定的实时时间。

... ...

This method causes the current thread (referred to here as T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object.此方法导致当前线程(此处称为 T)将自己置于此 object 的等待集中,然后放弃此 object 的任何和所有同步声明。

Thread T then becomes disabled for thread scheduling purposes and lies dormant until one of the following occurs:然后线程T出于线程调度目的而被禁用并处于休眠状态,直到发生以下情况之一:

  • ... ...

  • Some other thread interrupts thread T.其他一些线程中断线程 T。

  • ... ...

The thread T is then removed from the wait set for this object and re-enabled for thread scheduling.然后将线程T从此 object 的等待集中移除,并重新启用线程调度。 It competes in the usual manner with other threads for the right to synchronize on the object;它以通常的方式与其他线程竞争在 object 上同步的权利; once it has regained control of the object, all its synchronization claims on the object are restored to the status quo ante - that is, to the situation as of the time that the wait method was invoked.一旦它重新获得了对 object 的控制权,它对 object 的所有同步声明都将恢复到之前的状态 - 即,恢复到调用等待方法时的状态。 Thread T then returns from the invocation of the wait method.线程 T 然后从调用等待方法返回。 Thus, on return from the wait method, the synchronization state of the object and of thread T is exactly as it was when the wait method was invoked.因此,在从等待方法返回时,object 和线程 T 的同步 state 与调用等待方法时完全相同。

In other words, when thread 1 is interrupted by the main thread, it still has to wait for thread 2 to finish to relinquish its lock, and only then thread 1 will regain control of the lock and continue.换句话说,当线程1被主线程中断时,它仍然要等待线程2完成释放它的锁,然后线程1才能重新获得对锁的控制并继续。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM