public Token<AMRMTokenIdentifier> launchUAM()
      throws YarnException, IOException {
    this.connectionInitiated = true;

    // Blocking call to RM
    Token<AMRMTokenIdentifier> amrmToken = initializeUnmanagedAM(this.applicationId);

    // Creates the UAM connection
    createUAMProxy(amrmToken);
    return amrmToken;
  }
@Test
  public void testSeparateThreadWithoutBlockServiceStop() throws Exception {
    ApplicationAttemptId attemptId1 =
        ApplicationAttemptId.newInstance(ApplicationId.newInstance(Time.now(), 1), 1);
    Token<AMRMTokenIdentifier> token1 = uamPool.launchUAM("SC-1", this.conf,
        attemptId1.getApplicationId(), "default", "test-user", "SC-HOME", true, "SC-1", null);
    Assert.assertNotNull(token1);

    ApplicationAttemptId attemptId2 =
        ApplicationAttemptId.newInstance(ApplicationId.newInstance(Time.now(), 2), 1);
    Token<AMRMTokenIdentifier> token2 = uamPool.launchUAM("SC-2", this.conf,
        attemptId2.getApplicationId(), "default", "test-user", "SC-HOME", true, "SC-2", null);
    Assert.assertNotNull(token2);

    Map<String, UnmanagedApplicationManager> unmanagedAppMasterMap =
        uamPool.getUnmanagedAppMasterMap();
    Assert.assertNotNull(unmanagedAppMasterMap);
    Assert.assertEquals(2, unmanagedAppMasterMap.size());

    // try to stop uamPool
    uamPool.stop();
    Assert.assertTrue(uamPool.waitForServiceToStop(2000));
    // process force finish Application in a separate thread, not blocking the main thread
    Assert.assertEquals(Service.STATE.STOPPED, uamPool.getServiceState());

    // Wait for the thread to terminate, check if uamPool#unmanagedAppMasterMap is 0
    Thread finishApplicationThread = uamPool.getFinishApplicationThread();
    GenericTestUtils.waitFor(() -> !finishApplicationThread.isAlive(),
        100, 2000);
    Assert.assertEquals(0, unmanagedAppMasterMap.size());
  }