docs: public V get(final K key, final LogNode log) throws E, InterruptedException, NullSingletonException {
          final SingletonHolder<V> singletonHolder = map.get(key);
          V instance = null;
          if (singletonHolder != null) {
              // There is already a SingletonHolder in the map for this key -- get the value
              instance = singletonHolder.get();
          } else {
              // There is no SingletonHolder in the map for this key, need to create one
              // (need to handle race condition, hence the putIfAbsent call)
              final SingletonHolder<V> newSingletonHolder = new SingletonHolder<>();
              final SingletonHolder<V> oldSingletonHolder = map.putIfAbsent(key, newSingletonHolder);
              if (oldSingletonHolder != null) {
                  // There was already a singleton in the map for this key, due to a race condition --
                  // return the existing singleton
                  instance = oldSingletonHolder.get();
              } else {
                  try {
                      // Create a new instance
                      instance = newInstance(key, log);
  
                  } finally {
                      // Initialize newSingletonHolder with the new instance.
                      // Always need to call .set() even if an exception is thrown by newInstance()
                      // or newInstance() returns null, since .set() calls initialized.countDown().
                      // Otherwise threads that call .get() may end up waiting forever.
                      newSingletonHolder.set(instance);
                  }
              }
          }
          if (instance == null) {
              throw new NullSingletonException(key);
          } else {
              return instance;
          }
      }