code: public static HiveMetastoreClientPool get(final Properties properties, final Optional<String> metastoreURI)
        throws IOException {
      synchronized (HiveMetastoreClientPool.class) {
        if (poolCache == null) {
          poolCache = createPoolCache(properties);
        }
      }
      try {
        return poolCache.get(metastoreURI, new Callable<HiveMetastoreClientPool>() {
          @Override
          public HiveMetastoreClientPool call() throws Exception {
            return new HiveMetastoreClientPool(properties, metastoreURI);
          }
        });
      } catch (ExecutionException ee) {
        throw new IOException("Failed to get " + HiveMetastoreClientPool.class.getSimpleName(), ee.getCause());
      }
    }
docs: Get a {@link HiveMetastoreClientPool} for the requested metastore URI. Useful for using the same pools across
  different classes in the code base. Note that if a pool already exists for that metastore, the max number of
  objects available will be unchanged, and it might be lower than requested by this method.
  
  @param properties {@link Properties} used to generate the pool.
  @param metastoreURI URI of the Hive metastore. If absent, use default metastore.
  @return a {@link HiveMetastoreClientPool}.
  @throws IOException