public static String startup(final List<JVMClusterUtil.MasterThread> masters,
    final List<JVMClusterUtil.RegionServerThread> regionservers) throws IOException {
    // Implementation note: This method relies on timed sleeps in a loop. It's not great, and
    // should probably be re-written to use actual synchronization objects, but it's ok for now

    Configuration configuration = null;

    if (masters == null || masters.isEmpty()) {
      return null;
    }

    for (JVMClusterUtil.MasterThread t : masters) {
      configuration = t.getMaster().getConfiguration();
      t.start();
    }

    // Wait for an active master
    // having an active master before starting the region threads allows
    // then to succeed on their connection to master
    final int startTimeout = configuration != null
      ? Integer.parseInt(configuration.get("hbase.master.start.timeout.localHBaseCluster", "30000"))
      : 30000;
    waitForEvent(startTimeout, "active", () -> findActiveMaster(masters) != null);

    if (regionservers != null) {
      for (JVMClusterUtil.RegionServerThread t : regionservers) {
        t.start();
      }
    }

    // Wait for an active master to be initialized (implies being master)
    // with this, when we return the cluster is complete
    final int initTimeout = configuration != null
      ? Integer.parseInt(configuration.get("hbase.master.init.timeout.localHBaseCluster", "200000"))
      : 200000;
    waitForEvent(initTimeout, "initialized", () -> {
      JVMClusterUtil.MasterThread t = findActiveMaster(masters);
      // master thread should never be null at this point, but let's keep the check anyway
      return t != null && t.master.isInitialized();
    });

    return findActiveMaster(masters).master.getServerName().toString();
  }
Start the cluster. Waits until there is a primary master initialized and returns its address.
@return Address to use contacting primary master.
hbase-server/src/main/java/org/apache/hadoop/hbase/util/JVMClusterUtil.java