### Question:
AsyncProcess { protected void waitForNextTaskDone(long currentNumberOfTask) throws InterruptedIOException { while (currentNumberOfTask == tasksDone.get()) { try { synchronized (this.tasksDone) { this.tasksDone.wait(100); } } catch (InterruptedException e) { throw new InterruptedIOException("#" + id + ", interrupted." + " currentNumberOfTask=" + currentNumberOfTask + ", tableName=" + tableName + ", tasksDone=" + tasksDone.get()); } } } AsyncProcess(HConnection hc, TableName tableName, ExecutorService pool,
      AsyncProcessCallback<CResult> callback, Configuration conf,
      RpcRetryingCallerFactory rpcCaller); void submit(List<? extends Row> rows, boolean atLeastOne); void submitAll(List<? extends Row> rows); void sendMultiAction(final List<Action<Row>> initialActions,
                              Map<HRegionLocation, MultiAction<Row>> actionsByServer,
                              final int numAttempt,
                              final HConnectionManager.ServerErrorTracker errorsByServer); void waitUntilDone(); boolean hasError(); List<? extends Row> getFailedOperations(); void clearErrors(); RetriesExhaustedWithDetailsException getErrors();  }### Answer:
@Test public void testWaitForNextTaskDone() throws IOException { HConnection hc = createHConnection(); MyCB mcb = new MyCB(); final AsyncProcess ap = new MyAsyncProcess<Object>(hc, mcb, conf); ap.tasksSent.incrementAndGet(); final AtomicBoolean checkPoint = new AtomicBoolean(false); final AtomicBoolean checkPoint2 = new AtomicBoolean(false); Thread t = new Thread(){ @Override public void run(){ Threads.sleep(1000); Assert.assertFalse(checkPoint.get()); ap.tasksDone.incrementAndGet(); checkPoint2.set(true); } }; t.start(); ap.waitForNextTaskDone(0); checkPoint.set(true); while (!checkPoint2.get()){ Threads.sleep(1); } }