javainterrupted-exception

InterruptedException: How does Thread#sleep Know


As far as I understand it when someone calls interrupt on a thread it just sets a status flag on the thread. it is responsibility of interrupted Thread to handle the interrupt by periodically

  1. by checking whether or not it is interrupted

    or

  2. call a method which throws interruptedException which in turn checks for the flag as raises the exception

Now How does a thread which is put to sleep do it?

Does the interrupt() method only check the status of the thread and see that it is sleeping and raise the exception.

if it is the case does this also happens with wait() method?


Solution

  • Set flag, unpark, and wake

    The short answer is:

    Thread.interrupt() not only sets the interrupted flag, it also call a native method Thread.interrupt0() that wakes up Thread.sleep()ing threads, unparks threads in LockSupport.park() and wakes up threads in Object.wait().


    Note that the snippets below omit details. If you want the full source either follow the links to the OpenJDK Github repository or download the complete sources.

    If you look at the source of Thread.interrupt() you can see that it does three things:

    interrupted = true;
    interrupt0();  // inform VM of interrupt
    // thread may be blocked in an I/O operation
    Interruptible b = nioBlocker;
    b.interrupt(this);
    

    The method Thread.interrupt0() is mapped to the JVM method JVM_Interrupt:

    {"interrupt0",       "()V",        (void *)&JVM_Interrupt},
    

    That method locates the JavaThread instance (a C++ class) that is the native counterpart to the java.lang.Thread and calls the interrupt method on that instance:

    bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &receiver, NULL);
    receiver->interrupt();
    

    The JavaThread.interrupt() method then does the wake up and unpark of the thread:

      // For Thread.sleep
      _SleepEvent->unpark();
    
      // For JSR166 LockSupport.park
      parker()->unpark();
    
      // For ObjectMonitor and JvmtiRawMonitor
      _ParkEvent->unpark();
    

    These various unpark method notify the OS that the native thread should start running again (and then check the reason why it was reactivated).