code: public final T get(Object... args) {
          //Grab a read lock to try retrieving the object
          this.readLock.lock();
          try {
  
              //See if the object already exists
              T value = this.retrieve(args);
              if (this.invalid(value, args)) {
                  //Switch to a write lock
                  this.readLock.unlock();
                  this.writeLock.lock();
                  
                  //Check if it exists now, create it if it doesn't
                  try {
                      value = this.retrieve(args);
                  
                      if (this.invalid(value, args)) {
                          value = this.create(args);
                          
                          if (this.logger.isDebugEnabled()) {
                              this.logger.debug("Created new Object='" + value + "'");
                          }
                      }
                      else if (this.logger.isDebugEnabled()) {
                          this.logger.debug("Using retrieved Object='" + value + "'");
                      }
                  }
                  finally {
                      //switch back to the read lock
                      this.readLock.lock();
                      this.writeLock.unlock();
                  }
              }
              else if (this.logger.isDebugEnabled()) {
                  this.logger.debug("Using retrieved Object='" + value + "'");
              }
  
              return value;
          }
          finally {
              this.readLock.unlock();
          }
      }
docs: Double checking retrieval/creation of an object
  
  @param args Optional arguments to pass to {@link #retrieve(Object...)}, {@link #create(Object...)}, and {@link #invalid(Object, Object...)}.
  @return A retrieved or created object.