@VisibleForTesting
  Object optimizedGetObject(KeyInfo keyInfo, boolean isCreate, boolean generateCallbacks,
      Object localValue, boolean disableCopyOnRead, boolean preferCD,
      ClientProxyMembershipID requestingClient, EntryEventImpl clientEvent,
      boolean returnTombstones) {
    Object result = null;
    FutureResult thisFuture = new FutureResult(stopper);
    Future otherFuture = (Future) getFutures.putIfAbsent(keyInfo.getKey(), thisFuture);
    // only one thread can get their future into the map for this key at a time
    if (otherFuture != null) {
      try {
        Object[] valueAndVersion = (Object[]) otherFuture.get();
        if (valueAndVersion != null) {
          result = valueAndVersion[0];

          if (!preferCD && result instanceof CachedDeserializable) {
            CachedDeserializable cd = (CachedDeserializable) result;
            if (!disableCopyOnRead && (isCopyOnRead() || isProxy())) {
              result = cd.getDeserializedWritableCopy(null, null);
            } else {
              result = cd.getDeserializedForReading();
            }

          } else if (!disableCopyOnRead) {
            result = conditionalCopy(result);
          }
          // GEODE-8671: for PdxInstance, we need a new reference of it. Don't use the value from
          // the Future.
          if (!(result instanceof PdxInstance)) {
            if (clientEvent != null) {
              clientEvent.setVersionTag((VersionTag) valueAndVersion[1]);
            }
            // what was a miss is now a hit
            if (isCreate) {
              RegionEntry regionEntry = basicGetEntry(keyInfo.getKey());
              updateStatsForGet(regionEntry, true);
            }
            return result;
          }
        }
      } catch (InterruptedException ignore) {
        Thread.currentThread().interrupt();
        // TODO check a CancelCriterion here?
        return null;
      } catch (ExecutionException e) {
        // unexpected since there is no background thread
        // NOTE: this was creating InternalGemFireError and initCause with itself
        throw new InternalGemFireError(
            "unexpected exception", e);
      }
    }
    try {
      result =
          getObject(keyInfo, isCreate, generateCallbacks, localValue, disableCopyOnRead, preferCD,
              requestingClient, clientEvent, returnTombstones);

    } finally {
      if (otherFuture == null) {
        if (result != null) {
          VersionTag tag = clientEvent == null ? null : clientEvent.getVersionTag();
          thisFuture.set(new Object[] {result, tag});
        } else {
          thisFuture.set(null);
        }
        getFutures.remove(keyInfo.getKey());
      }
    }

    return result;
  }
optimized to only allow one thread to do a search/load, other threads wait on a future
geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java