public static void runMttTest(BuddyAllocator a, FutureTask<?>[] allocTasks,
      CountDownLatch cdlIn, CountDownLatch cdlOut, FutureTask<Void> dumpTask,
      FutureTask<Void> defragTask, AtomicBoolean defragStopped, int totalSize, int maxAllocSize) {
    Throwable t = null;
    try {
      cdlIn.await(); // Wait for all threads to be ready.
    } catch (InterruptedException e) {
      throw new RuntimeException(e);
    }
    cdlOut.countDown(); // Release them at the same time.
    for (int i = 0; i < allocTasks.length; ++i) {
      try {
        Object result = allocTasks[i].get();
        LOG.info("" + result);
      } catch (Throwable tt) {
        LOG.error("Test callable failed", tt);
        if (t == null) {
          a.dumpTestLog();
          t = tt;
        }
      }
    }
    dumpTask.cancel(true);
    if (defragTask != null) {
      defragStopped.set(true);
      try {
        defragTask.get();
      } catch (Throwable tt) {
        LOG.error("Defragmentation thread failed", t);
        if (t == null) {
          a.dumpTestLog();
          t = tt;
        }
      }
    }
    if (t != null) {
      throw new RuntimeException("One of the errors", t);
    }
    // All the tasks should have deallocated their stuff. Make sure we can allocate everything.
    LOG.info("Allocator state after all the tasks: " + a.testDump());
    try {
      allocate(a, totalSize / maxAllocSize, maxAllocSize, 0);
    } catch (Throwable tt) {
      a.dumpTestLog();
      throw tt;
    }
  }
This relies on allocations basically being sequential, no internal reordering. Rather,
the specific paths it takes do; all the scenarios should work regardless of allocation.
llap-server/src/test/org/apache/hadoop/hive/llap/cache/TestBuddyAllocatorForceEvict.java