// Private since we can't add a vtable slot in 4.1.x. private void exitNoChecks(int status) { if (runShutdownHooks()) exitInternal(status); // Someone else already called runShutdownHooks(). // Make sure we are not/no longer in the shutdownHooks set. // And wait till the thread that is calling runShutdownHooks() finishes. synchronized (libpath) { if (shutdownHooks != null) { shutdownHooks.remove(Thread.currentThread()); // Interrupt the exit sequence thread, in case it was waiting // inside a join on our thread. exitSequence.interrupt(); // Shutdown hooks are still running, so we clear status to // make sure we don't halt. status = 0; } } // If exit() is called again after the shutdown hooks have run, but // while finalization for exit is going on and the status is non-zero // we halt immediately. if (status != 0) exitInternal(status); while (true) try { exitSequence.join(); } catch (InterruptedException e) { // Ignore, we've suspended indefinitely to let all shutdown // hooks complete, and to let any non-zero exits through, because // this is a duplicate call to exit(0). } }
/** * Waits for the runtime thread to stop. This interrupts the thread currently running the * runnable and then waits for it to exit. */ public void stop() { Thread threadToStop; synchronized (this) { threadToStop = thread; thread = null; } if (threadToStop == null) { throw new IllegalStateException("not running"); } threadToStop.interrupt(); while (true) { try { threadToStop.join(); return; } catch (InterruptedException ignored) { } } }
/** * Parks the current thread for a particular number of nanoseconds, or indefinitely. If not * indefinitely, this method unparks the thread after the given number of nanoseconds if no other * thread unparks it first. If the thread has been "preemptively unparked," this method cancels * that unparking and returns immediately. This method may also return spuriously (that is, * without the thread being told to unpark and without the indicated amount of time elapsing). * * <p>See {@link java.util.concurrent.locks.LockSupport} for more in-depth information of the * behavior of this method. * * <p>This method must only be called when <code>this</code> is the current thread. * * @param nanos number of nanoseconds to park for or <code>0</code> to park indefinitely * @throws IllegalArgumentException thrown if <code>nanos < 0</code> * @hide for Unsafe */ public void parkFor(long nanos) { VMThread vmt = vmThread; if (vmt == null) { // Running threads should always have an associated vmThread. throw new AssertionError(); } synchronized (vmt) { switch (parkState) { case ParkState.PREEMPTIVELY_UNPARKED: { parkState = ParkState.UNPARKED; break; } case ParkState.UNPARKED: { long millis = nanos / NANOS_PER_MILLI; nanos %= NANOS_PER_MILLI; parkState = ParkState.PARKED; try { vmt.wait(millis, (int) nanos); } catch (InterruptedException ex) { interrupt(); } finally { /* * Note: If parkState manages to become * PREEMPTIVELY_UNPARKED before hitting this * code, it should left in that state. */ if (parkState == ParkState.PARKED) { parkState = ParkState.UNPARKED; } } break; } default /*parked*/: { throw new AssertionError("shouldn't happen: attempt to repark"); } } } }
public void finish() { stop = true; thread.interrupt(); }
public synchronized void interrupt() { if (thread == null) { throw new IllegalStateException("not running"); } thread.interrupt(); }