@Test
  public void testConcurrentPMFInitialize() throws Exception {
    final String dataSourceProp = "datanucleus.connectionPool.maxPoolSize";
    // Barrier is used to ensure that all threads start race at the same time
    final int numThreads = 10;
    final int numIteration = 50;
    final CyclicBarrier barrier = new CyclicBarrier(numThreads);
    final AtomicInteger counter = new AtomicInteger(0);
    ExecutorService executor = newFixedThreadPool(numThreads);
    List<Future<Void>> results = new ArrayList<>(numThreads);
    for (int i = 0; i < numThreads; i++) {
      final Random random = new Random();
      Configuration conf = MetastoreConf.newMetastoreConf();
      // DN class initialization can reach a deadlock situation
      // in case the one holding the write lock doesn't get a connection from the CP manager
      conf.set(dataSourceProp, Integer.toString( 2 * numThreads ));
      MetaStoreTestUtils.setConfForStandloneMode(conf);
      results.add(executor.submit(new Callable<Void>() {
        @Override
        public Void call() throws Exception {
          // each thread gets its own ObjectStore to simulate threadLocal store
          ObjectStore objectStore = new ObjectStore();
          barrier.await();
          for (int j = 0; j < numIteration; j++) {
            // set connectionPool to a random value to increase the likelihood of pmf
            // re-initialization
            int randomNumber = random.nextInt(100);
            if (randomNumber % 2 == 0) {
              objectStore.setConf(conf);
            } else {
              Assert.assertNotNull(objectStore.getPersistenceManager());
            }
            counter.getAndIncrement();
          }
          return null;
        }
      }));
    }
    for (Future<Void> future : results) {
      future.get(120, TimeUnit.SECONDS);
    }
    Assert.assertEquals("Unexpected number of setConf calls", numIteration * numThreads,
        counter.get());
  }
This test calls ObjectStore.setConf methods from multiple threads. Each threads uses its
own instance of ObjectStore to simulate thread-local objectstore behaviour.
@throws Exception
standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestObjectStore.java