### Question:
MultiPointOutputStream { void runSync() throws IOException { Util.d(TAG, "OutputStream start flush looper task[" + task.getId() + "] with " + "syncBufferIntervalMills[" + syncBufferIntervalMills + "] " + "syncBufferSize[" + syncBufferSize + "]"); runSyncThread = Thread.currentThread(); long nextParkMills = syncBufferIntervalMills; flushProcess(); while (true) { parkThread(nextParkMills); inspectStreamState(state); if (state.isStreamsEndOrChanged()) { Util.d(TAG, "runSync state change isNoMoreStream[" + state.isNoMoreStream + "]" + " newNoMoreStreamBlockList[" + state.newNoMoreStreamBlockList + "]"); if (allNoSyncLength.get() > 0) { flushProcess(); } for (Integer blockIndex : state.newNoMoreStreamBlockList) { final Thread parkedThread = parkedRunBlockThreadMap.get(blockIndex); parkedRunBlockThreadMap.remove(blockIndex); if (parkedThread != null) unparkThread(parkedThread); } if (state.isNoMoreStream) { final int size = parkedRunBlockThreadMap.size(); for (int i = 0; i < size; i++) { final Thread parkedThread = parkedRunBlockThreadMap.valueAt(i); if (parkedThread != null) unparkThread(parkedThread); } parkedRunBlockThreadMap.clear(); break; } else { continue; } } if (isNoNeedFlushForLength()) { nextParkMills = syncBufferIntervalMills; continue; } nextParkMills = getNextParkMillisecond(); if (nextParkMills > 0) { continue; } flushProcess(); nextParkMills = syncBufferIntervalMills; } Util.d(TAG, "OutputStream stop flush looper task[" + task.getId() + "]"); } MultiPointOutputStream(@NonNull final DownloadTask task,
                           @NonNull BreakpointInfo info,
                           @NonNull DownloadStore store,
                           @Nullable Runnable syncRunnable);  MultiPointOutputStream(@NonNull DownloadTask task,
                                  @NonNull BreakpointInfo info,
                                  @NonNull DownloadStore store); synchronized void write(int blockIndex, byte[] bytes, int length); void cancelAsync(); synchronized void cancel(); void done(int blockIndex); void inspectComplete(int blockIndex); void setRequireStreamBlocks(List<Integer> requireStreamBlocks); void catchBlockConnectException(int blockIndex);  }### Answer:
@Test public void runSync() throws IOException { final MultiPointOutputStream.StreamsState state = spy(new MultiPointOutputStream.StreamsState()); multiPointOutputStream.state = state; when(state.isStreamsEndOrChanged()).thenReturn(false, false, false, true); doNothing().when(multiPointOutputStream).parkThread(anyLong()); doNothing().when(multiPointOutputStream).unparkThread(any(Thread.class)); doNothing().when(multiPointOutputStream).flushProcess(); doNothing().when(multiPointOutputStream).inspectStreamState(state); final Thread thread0 = mock(Thread.class); final Thread thread1 = mock(Thread.class); multiPointOutputStream.parkedRunBlockThreadMap.put(0, thread0); multiPointOutputStream.parkedRunBlockThreadMap.put(1, thread1); multiPointOutputStream.allNoSyncLength.set(1); state.newNoMoreStreamBlockList.add(0); state.newNoMoreStreamBlockList.add(1); state.isNoMoreStream = true; when(multiPointOutputStream.isNoNeedFlushForLength()).thenReturn(true, false); when(multiPointOutputStream.getNextParkMillisecond()).thenReturn(1L, -1L); multiPointOutputStream.runSync(); verify(multiPointOutputStream, times(3)).flushProcess(); assertThat(multiPointOutputStream.parkedRunBlockThreadMap.size()).isZero(); verify(multiPointOutputStream).unparkThread(eq(thread0)); verify(multiPointOutputStream).unparkThread(eq(thread1)); }