@Override
    public void run() {
      final LockHeartbeatRequest lockHeartbeatRequest =
        LockHeartbeatRequest.newBuilder().setProcId(procId).build();

      LockHeartbeatResponse response;
      while (true) {
        try {
          response = stub.lockHeartbeat(null, lockHeartbeatRequest);
        } catch (Exception e) {
          e = ProtobufUtil.handleRemoteException(e);
          locked.set(false);
          LOG.error("Heartbeat failed, releasing " + EntityLock.this, e);
          abort.abort("Heartbeat failed", e);
          return;
        }
        if (!isLocked() && response.getLockStatus() == LockHeartbeatResponse.LockStatus.LOCKED) {
          locked.set(true);
          latch.countDown();
        } else
          if (isLocked() && response.getLockStatus() == LockHeartbeatResponse.LockStatus.UNLOCKED) {
            // Lock timed out.
            locked.set(false);
            abort.abort("Lock timed out.", null);
            return;
          }

        try {
          // If lock not acquired yet, poll faster so we can notify faster.
          long sleepTime = 1000;
          if (isLocked()) {
            // If lock acquired, then use lock timeout to determine heartbeat rate.
            // If timeout is <heartbeatTimeBuffer, send back to back heartbeats.
            sleepTime = Math.max(response.getTimeoutMs() - heartbeatTimeBuffer, 1);
          }
          if (testingSleepTime != 0) {
            sleepTime = testingSleepTime;
          }
          Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
          // Since there won't be any more heartbeats, assume lock will be lost.
          locked.set(false);
          if (!this.shutdown) {
            LOG.error("Interrupted, releasing " + this, e);
            abort.abort("Worker thread interrupted", e);
          }
          return;
        }
      }
    }
Returns Shuts down the thread clean and quietly.
hbase-server/src/main/java/org/apache/hadoop/hbase/client/locking/EntityLock.java