@Test(timeout = 5000)
public void testConcurrentRegister()
    throws InterruptedException, ExecutionException {

  ExecutorService threadpool = Executors.newCachedThreadPool();
  ExecutorCompletionService<RegisterApplicationMasterResponse> compSvc =
      new ExecutorCompletionService<>(threadpool);
  Object syncObj = MockResourceManagerFacade.getRegisterSyncObj();
  // Two register threads
  synchronized (syncObj) {
    // Make sure first thread will block within RM, before the second thread
    // starts
    LOG.info("Starting first register thread");
    compSvc.submit(new ConcurrentRegisterAMCallable());
    try {
      LOG.info("Test main starts waiting for the first thread to block");
      syncObj.wait();
      LOG.info("Test main wait finished");
    } catch (Exception e) {
      LOG.info("Test main wait interrupted", e);
    }
  }
  // The second thread will get already registered exception from RM.
  LOG.info("Starting second register thread");
  compSvc.submit(new ConcurrentRegisterAMCallable());
  // Notify the first register thread to return
  LOG.info("Let first blocked register thread move on");
  synchronized (syncObj) {
    syncObj.notifyAll();
  }
  // Both thread should return without exception
  RegisterApplicationMasterResponse response = compSvc.take().get();
  Assert.assertNotNull(response);
  response = compSvc.take().get();
  Assert.assertNotNull(response);
  threadpool.shutdown();
}