code: private void start(Runnable timeoutTask, long remainingNanos) {
          lock.writeLock().lock();
          try {
              this.timeoutTask = timeoutTask;
  
              this.start = System.nanoTime();
              this.targetEnd = start + remainingNanos;
  
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                  debugTime(">Start  {0}", this.start);
                  debugTime(">Target {0}", this.targetEnd);
                  debugTime(">Now    {0}", this.start);
                  debugTime(">Remain {0}", remainingNanos);
              }
  
              Runnable task = () -> {
                  timeout();
              };
  
              if (remainingNanos > FTConstants.MIN_TIMEOUT_NANO) {
                  this.future = scheduledExecutorService.schedule(task, remainingNanos, TimeUnit.NANOSECONDS);
              } else {
                  task.run();
              }
          } finally {
              lock.writeLock().unlock();
          }
      }
docs: This is the method which actually starts the timer
  
  WARNING: This method uses System.nanoTime(). nanoTime is a point in time relative to an arbitrary point (fixed at runtime).
  As a result, it could be positive or negative and will not bare any relation to the actual time ... it's just a relative measure.
  Also, since it could be massively positive or negative, caution must be used when doing comparisons due to the possibility
  of numerical overflow e.g. one should use t1 - t0 < 0, not t1 < t0
  The reason we use this here is that it not affected by changes to the system clock at runtime
  
  @param timeoutTask
  @param remainingNanos