Download File
Download Project
Settings
Line Wrap
Themes
default
ambiance
bespin
dracula
eclipse
material
mbo
mdn-like
neat
solarized dark
ttcn
zenburn
CountingAppExecutors.java
/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.example.github.util; import com.android.example.github.AppExecutors; import android.support.annotation.NonNull; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; public class CountingAppExecutors { private final Object LOCK = new Object(); private int taskCount = 0; private AppExecutors appExecutors; public CountingAppExecutors() { Runnable increment = () -> { synchronized (LOCK) { taskCount--; if (taskCount == 0) { LOCK.notifyAll(); } } }; Runnable decrement = () -> { synchronized (LOCK) { taskCount++; } }; appExecutors = new AppExecutors( new CountingExecutor(increment, decrement), new CountingExecutor(increment, decrement), new CountingExecutor(increment, decrement)); } public AppExecutors getAppExecutors() { return appExecutors; } public void drainTasks(int time, TimeUnit timeUnit) throws InterruptedException, TimeoutException { long end = System.currentTimeMillis() + timeUnit.toMillis(time); while (true) { synchronized (LOCK) { if (taskCount == 0) { return; } long now = System.currentTimeMillis(); long remaining = end - now; if (remaining > 0) { LOCK.wait(remaining); } else { throw new TimeoutException("could not drain tasks"); } } } } private static class CountingExecutor implements Executor { private final Executor delegate = Executors.newSingleThreadExecutor(); private final Runnable increment; private final Runnable decrement; public CountingExecutor(Runnable increment, Runnable decrement) { this.increment = increment; this.decrement = decrement; } @Override public void execute(@NonNull Runnable command) { increment.run(); delegate.execute(() -> { try { command.run(); } finally { decrement.run(); } }); } } }