private void runExpirationThread() {
    try {
      while (true) {
        TezSessionPoolSession nextToExpire = null;
        while (true) {
          // Restart the sessions until one of them refuses to restart.
          nextToExpire = expirationQueue.take();
          LOG.debug("Seeing if we can expire [{}]", nextToExpire);
          try {
            if (!nextToExpire.tryExpire(false)) break;
          } catch (Exception e) {
            // Reopen happens even when close fails, so there's not much to do here.
            LOG.error("Failed to expire session " + nextToExpire + "; ignoring", e);
            nextToExpire = null;
            break; // Not strictly necessary; do the whole queue check again.
          }
          LOG.info("Tez session [" + nextToExpire + "] has expired");
        }
        if (nextToExpire != null && LOG.isDebugEnabled()) {
          LOG.debug("[" + nextToExpire + "] is not ready to expire; adding it back");
        }

        // See addToExpirationQueue for why we re-check the queue.
        synchronized (expirationQueue) {
          // Add back the non-expired session. No need to notify, we are the only ones waiting.
          if (nextToExpire != null) {
            expirationQueue.add(nextToExpire);
          }
          nextToExpire = expirationQueue.peek();
          if (nextToExpire != null) {
            // Add some margin to the wait to avoid rechecking close to the boundary.
            long timeToWaitMs = (nextToExpire.getExpirationNs() - System.nanoTime()) / 1000000L;
            timeToWaitMs = Math.max(1, timeToWaitMs + 10);
            LOG.debug("Waiting for ~{}ms to expire [{}]", timeToWaitMs, nextToExpire);
            expirationQueue.wait(timeToWaitMs);
          } else if (LOG.isDebugEnabled()) {
            // Don't wait if empty - go to take() above, that will wait for us.
            LOG.debug("Expiration queue is empty");
          }
        }
      }
    } catch (InterruptedException e) {
      LOG.info("Expiration thread is exiting due to an interruption");
    }
  }
Logic for the thread that tracks session expiration and restarts sessions in background.
ql/src/java/org/apache/hadoop/hive/ql/exec/tez/SessionExpirationTracker.java