void unpark() { // This is racy with removeWaiter. The consequence of the race is that we may spuriously call // unpark even though the thread has already removed itself from the list. But even if we did // use a CAS, that race would still exist (it would just be ever so slightly smaller). Thread w = thread; if (w != null) { thread = null; LockSupport.unpark(w); } } }
void unpark() { // This is racy with removeWaiter. The consequence of the race is that we may spuriously call // unpark even though the thread has already removed itself from the list. But even if we did // use a CAS, that race would still exist (it would just be ever so slightly smaller). Thread w = thread; if (w != null) { thread = null; LockSupport.unpark(w); } } }
protected void pokeReader() { // wake up the reader... there's stuff to do, data to read hasReadAhead = false; LockSupport.unpark( this ); } }
@Override public void unpark( Thread thread ) { LockSupport.unpark( thread ); } }
private void unparkEvictor() { if ( evictorParked ) { evictorParked = false; LockSupport.unpark( evictionThread ); } }
void unpark() { LockSupport.unpark( owner ); } }
private void wakeUpEmittingThread() { LockSupport.unpark(emittingThread); }
public void stop() { stopped = true; LockSupport.unpark( timeKeeper ); } }
/** * Initiate the shut down process of this {@code AsyncEvents} instance. * <p> * This call does not block or otherwise wait for the background thread to terminate. */ public void shutdown() { assert !shutdown : "Already shut down"; shutdown = true; LockSupport.unpark( backgroundThread ); }
void unpark() { // This is racy with removeWaiter. The consequence of the race is that we may spuriously call // unpark even though the thread has already removed itself from the list. But even if we did // use a CAS, that race would still exist (it would just be ever so slightly smaller). Thread w = thread; if (w != null) { thread = null; LockSupport.unpark(w); } } }
public void unpark() { LockSupport.unpark( thread ); }
private void unparkSuccessor( Node waiters ) { if ( waiters.getClass() == Waiter.class ) { Waiter waiter = (Waiter) waiters; waiter.state = waiterStateSuccessor; LockSupport.unpark( waiter.waitingThread ); } }
void enqueueTask( ScheduledJobHandle newTasks ) { delayedTasks.offer( newTasks ); LockSupport.unpark( timeKeeper ); }
/** * Tries to artificially match a data node -- used by remove. */ final boolean tryMatchData() { // assert isData; Object x = item; if (x != null && x != this && casItem(x, null)) { LockSupport.unpark(waiter); return true; } return false; }
private void unlock(Thread waiter) { try { LockSupport.unpark(waiter); } catch (Throwable x) { handleUncaughtException(x); } }
/** * Tries to artificially match a data node -- used by remove. */ final boolean tryMatchData() { // assert isData; Object x = item; if (x != null && x != this && casItem(x, null)) { LockSupport.unpark(waiter); return true; } return false; }
private void addNotice(Notice notice) { atomicallyUpdateStateRef( oldState -> { if (oldState.pendingNotices.size() > 10000) { //don't let pendingNotices grow indefinitely throw new ISE("There are too many [%d] pendingNotices.", oldState.pendingNotices.size()); } ImmutableList.Builder<Notice> builder = ImmutableList.builder(); builder.addAll(oldState.pendingNotices); builder.add(notice); return new LookupUpdateState(oldState.lookupMap, builder.build(), oldState.noticesBeingHandled); } ); LockSupport.unpark(mainThread); }
@Override Void runInterruptibly() throws Exception { slowChannel.doBegin(); isInterruptibleRegistered.countDown(); try { new CountDownLatch(1).await(); // the interrupt will wake us up } catch (InterruptedException ie) { // continue } LockSupport.unpark(Thread.currentThread()); // simulate a spurious wakeup. return null; }
/** * Interrupts the running task. Because this internally calls {@link Thread#interrupt()} which can in turn * invoke arbitrary code it is not safe to call while holding a lock. */ final void interruptTask() { // Since the Thread is replaced by DONE before run() invokes listeners or returns, if we succeed // in this CAS, there's no risk of interrupting the wrong thread or interrupting a thread that // isn't currently executing this task. Runnable currentRunner = get(); if (currentRunner instanceof Thread && compareAndSet(currentRunner, INTERRUPTING)) { // Thread.interrupt can throw aribitrary exceptions due to the nio InterruptibleChannel API // This will make sure that tasks don't get stuck busy waiting. // Some of this is fixed in jdk11 (see https://bugs.openjdk.java.net/browse/JDK-8198692) but // not all. See the test cases for examples on how this can happen. try { ((Thread) currentRunner).interrupt(); } finally { Runnable prev = getAndSet(DONE); if (prev == PARKED) { LockSupport.unpark((Thread) currentRunner); } } } }
public void testRemoveWaiter_interruption() throws Exception { final AbstractFuture<String> future = new AbstractFuture<String>() {}; WaiterThread waiter1 = new WaiterThread(future); waiter1.start(); waiter1.awaitWaiting(); WaiterThread waiter2 = new WaiterThread(future); waiter2.start(); waiter2.awaitWaiting(); // The waiter queue should be waiter2->waiter1 // This should wake up waiter1 and cause the waiter1 node to be removed. waiter1.interrupt(); waiter1.join(); waiter2.awaitWaiting(); // should still be blocked LockSupport.unpark(waiter2); // spurious wakeup waiter2.awaitWaiting(); // should eventually re-park future.set(null); waiter2.join(); }