public static void main(String[] args) throws Exception {
    final int totalServiceDefinitions = Integer.parseInt(args[0]);
    final int threadPoolSize = Integer.parseInt(args[1]);

    final ServiceContainer container = ServiceContainer.Factory.create();
    final ThreadPoolExecutor executor =
        new ThreadPoolExecutor(
            threadPoolSize,
            threadPoolSize,
            1000,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>());
    container.setExecutor(executor);

    BatchBuilder batch = container.batchBuilder();

    final LatchedFinishListener listener = new LatchedFinishListener();

    final Value<Field> testFieldValue =
        new CachedValue<Field>(
            new LookupFieldValue(new ImmediateValue<Class<?>>(TestObject.class), "test"));

    final List<Value<Class<?>>> params =
        Collections.singletonList((Value<Class<?>>) new ImmediateValue<Class<?>>(TestObject.class));
    final List<Value<Method>> setterMethodValues = new ArrayList<Value<Method>>(5);
    for (int i = 0; i < 5; i++)
      setterMethodValues.add(
          new CachedValue<Method>(
              new LookupMethodValue(
                  new ImmediateValue<Class<?>>(TestObject.class), "setOther" + (i), params)));

    for (int i = 0; i < totalServiceDefinitions; i++) {
      final TestObject testObject = new TestObject("test" + i);
      final TestObjectService service = new TestObjectService(testObject);
      final ServiceBuilder<TestObject> builder =
          batch.addService(ServiceName.of(("test" + i).intern()), service).addListener(listener);

      final Object injectedValue = new Object();
      //            builder.addInjection(injectedValue).toFieldValue(testFieldValue);

      int nextDivByFive = (5 - (i % 5)) + i;
      int numDeps = Math.min(nextDivByFive - i, totalServiceDefinitions - i - 1);
      for (int j = 0; j < numDeps; j++) {
        int depId = i + j + 1;
        if (depId % 5 == 0) continue;

        //                builder.addDependency(ServiceName.of(("test" +
        // depId).intern())).toMethodValue(setterMethodValues.get(j),
        // Collections.singletonList(Values.injectedValue()));
      }
    }

    batch.install();
    listener.await();
    System.out.println(totalServiceDefinitions + " : " + listener.getElapsedTime() / 1000.0);
    container.shutdown();
    executor.shutdown();
  }
 void shutdown() {
   if (allowContainerShutdown) {
     serviceContainer.shutdown();
     synchronized (shutdownInitiated) {
       shutdownInitiated.set(true);
       LOGGER.debugf("shutdownInitiated.notifyAll");
       shutdownInitiated.notifyAll();
     }
   }
 }
    private void exit() {

      if (serviceContainer != null) {
        try {
          serviceContainer.shutdown();

          serviceContainer.awaitTermination();
        } catch (RuntimeException rte) {
          throw rte;
        } catch (InterruptedException ite) {
          ite.printStackTrace();
          Thread.currentThread().interrupt();
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      }
      if (controlledProcessStateService != null) {
        controlledProcessStateService.removePropertyChangeListener(processStateListener);
        controlledProcessStateService = null;
      }
      if (executorService != null) {
        try {
          executorService.shutdown();

          // 10 secs is arbitrary, but if the service container is terminated,
          // no good can happen from waiting for ModelControllerClient requests to complete
          executorService.awaitTermination(10, TimeUnit.SECONDS);
        } catch (RuntimeException rte) {
          throw rte;
        } catch (InterruptedException ite) {
          ite.printStackTrace();
          Thread.currentThread().interrupt();
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      }

      if (uninstallStdIo) {
        try {
          StdioContext.uninstall();
        } catch (IllegalStateException ignored) {
          // something else already did
        }
      }

      SystemExiter.initialize(SystemExiter.Exiter.DEFAULT);
    }
 @Override
 public void run() {
   final ServiceContainer sc;
   final ControlledProcessState ps;
   synchronized (this) {
     down = true;
     sc = container;
     ps = processState;
   }
   try {
     if (ps != null) {
       ps.setStopping();
     }
   } finally {
     if (sc != null) {
       SystemExiter.logBeforeExit(HostControllerLogger.ROOT_LOGGER::shutdownHookInvoked);
       final CountDownLatch latch = new CountDownLatch(1);
       sc.addTerminateListener(
           new ServiceContainer.TerminateListener() {
             @Override
             public void handleTermination(Info info) {
               latch.countDown();
             }
           });
       sc.shutdown();
       // wait for all services to finish.
       for (; ; ) {
         try {
           latch.await();
           break;
         } catch (InterruptedException e) {
         }
       }
     }
   }
 }
 @AfterClass
 public static void testServerStartupAndShutDown() throws Exception {
   container.shutdown();
   container.awaitTermination();
   Assert.assertTrue(container.isShutdownComplete());
 }