public override void Run() { Debug.Assert(_backgroundThread == null, "A thread is already running " + _backgroundThread); _backgroundThread = Thread.CurrentThread; _startupLatch.release(); try { do { AsyncEvent events = _stackUpdater.getAndSet(this, _endSentinel); Process(events); if (_stack == _endSentinel && !_shutdown) { LockSupport.park(this); } } while (!_shutdown); AsyncEvent events = _stackUpdater.getAndSet(this, _shutdownSentinel); Process(events); } finally { _backgroundThread = null; _shutdownLatch.release(); } }
/// <summary> /// 线程休眠且检查是否被中断唤醒 这儿可能有问题!!!!! /// </summary> /// <returns></returns> private bool parkAndCheckInterrupt() { try { LockSupport.park(this); return(true); } catch (ThreadInterruptedException e) { return(false); } }
/// <summary> /// 结束运行 依次唤醒等待get结果的节点 带超时机制 /// </summary> /// <param name="timed"></param> /// <param name="nanos"></param> /// <returns></returns> private int awaitDone(bool timed, long nanos) { long deadline = timed ? DateTime.Now.Ticks + nanos : 0L; WaitNode q = null; bool queued = false; for (; ;) { //if (Thread.interrupted()) { // removeWaiter(q); // throw new ThreadInterruptedException(); //} int s = state; if (s > COMPLETING) { if (q != null) { q.thread = null; } return(s); } else if (s == COMPLETING)// cannot time out yet { Thread.Yield(); } else if (q == null) { q = new WaitNode(); } else if (!queued) { queued = Interlocked.CompareExchange <WaitNode>(ref waiters, q, q.next = waiters) == q.next; } else if (timed) { nanos = deadline - DateTime.Now.Ticks; if (nanos <= 0L) { removeWaiter(q); return(state); } LockSupport.parkNanos(this, nanos); } else { LockSupport.park(this); } } }
private void refill() { int count = 200; while (fillBacklog() == false) { if (count > 100) { ; } else if (count > 0) { Thread.yield(); } else { LockSupport.park(); } count = count - 1; } }
/// <summary> /// Wait for the latch to be released, blocking the current thread if necessary. /// <para> /// This method returns immediately if the latch has already been released. /// </para> /// </summary> public virtual void Await() { // Put in a local variable to avoid volatile reads we don't need. Node state = _stack; if (state != _released) { // The latch hasn't obviously already been released, so we want to add a waiter to the stack. Trouble is, // we might race with release here, so we need to re-check for release after we've modified the stack. Waiter waiter = new Waiter(); state = ( Node )UnsafeUtil.getAndSetObject(this, _stackOffset, waiter); if (state == _released) { // If we get 'released' back from the swap, then we raced with release, and it is our job to put the // released sentinel back. Doing so can, however, return more waiters that have added themselves in // the mean time. If we find such waiters, then we must make sure to unpark them. Note that we will // never get a null back from this swap, because we at least added our own waiter earlier. Node others = ( Node )UnsafeUtil.getAndSetObject(this, _stackOffset, _released); // Set our next pointer to 'released' as a signal to other threads who might be going through the // stack in the isReleased check. waiter.Next = _released; UnparkAll(others); } else { // It looks like the latch hasn't yet been released, so we are going to park. Before that, we must // assign a non-null value to our next pointer, so other threads will know that we have been properly // enqueued. We use the 'end' sentinel as a marker when there's otherwise no other next node. waiter.Next = state == null ? _end : state; do { // Park may wake up spuriously, so we have to loop on it until we observe from the state of the // stack, that the latch has been released. LockSupport.park(this); } while (!IsReleased(waiter)); } } }