code: public V getOrLoad(K key, CacheLoader<V> loader) {
          V item;
          
         // synchronized( this ) {
              if( containsKey(key) ) {
                  return get(key);
              }
          //}
          item = loader.load();
          if( item != null ) {
              putIfAbsent(key, item);
              return get(key);
          }
          else {
              return null;
          }
      }
docs: Retrieves the value for the specified key. If no value is present, this method
  will attempt to load a value and place it into the cache. This method appears
  atomic in accordance with the contract of a @{link ConcurrentMap}, but any
  required loading will actually occur outside of a synchronous block, thus allowing
  for other operations on the cache while a load is in process. In the rare
  instance that two loads occur simultaneously, the result of the first completed
  load will be stored in the cache and the second will be discarded. As a result,
  the return value of both calls will be the item loaded from the first load to
  complete.
  @param key the key being sought
  @param loader a loader to load a new value if a value is missing
  @return the value matching the specified key or <code>null</code> if no object
  exists in the system matching the desired key