code: private void removeWaiter(Waiter node) {
      node.thread = null; // mark as 'deleted'
      restart:
      while (true) {
        Waiter pred = null;
        Waiter curr = waiters;
        if (curr == Waiter.TOMBSTONE) {
          return; // give up if someone is calling complete
        }
        Waiter succ;
        while (curr != null) {
          succ = curr.next;
          if (curr.thread != null) { // we aren't unlinking this node, update pred.
            pred = curr;
          } else if (pred != null) { // We are unlinking this node and it has a predecessor.
            pred.next = succ;
            if (pred.thread == null) { // We raced with another node that unlinked pred. Restart.
              continue restart;
            }
          } else if (!ATOMIC_HELPER.casWaiters(this, curr, succ)) { // We are unlinking head
            continue restart; // We raced with an add or complete
          }
          curr = succ;
        }
        break;
      }
    }
docs: Marks the given node as 'deleted' (null waiter) and then scans the list to unlink all deleted
  nodes. This is an O(n) operation in the common case (and O(n^2) in the worst), but we are saved
  by two things.
  
  <ul>
  <li>This is only called when a waiting thread times out or is interrupted. Both of which
  should be rare.
  <li>The waiters list should be very short.
  </ul>