am f9e2d271: Use a single background executor.

* commit 'f9e2d271ca101a53a6aac772ca770242805793ef':
  Use a single background executor.
main
Dan Zivkovic 2015-03-09 21:07:46 +00:00 committed by Android Git Automerger
commit 1fa61ab61b
6 changed files with 15 additions and 52 deletions

View File

@ -56,7 +56,7 @@ public class ContactsContentObserver implements Runnable {
mContentObserver = new ContentObserver(null /* handler */) { mContentObserver = new ContentObserver(null /* handler */) {
@Override @Override
public void onChange(boolean self) { public void onChange(boolean self) {
ExecutorUtils.getExecutorForDynamicLanguageModelUpdate() ExecutorUtils.getBackgroundExecutor()
.execute(ContactsContentObserver.this); .execute(ContactsContentObserver.this);
} }
}; };

View File

@ -444,7 +444,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
final Locale[] locales, final DictionaryInitializationListener listener) { final Locale[] locales, final DictionaryInitializationListener listener) {
final CountDownLatch latchForWaitingLoadingMainDictionary = new CountDownLatch(1); final CountDownLatch latchForWaitingLoadingMainDictionary = new CountDownLatch(1);
mLatchForWaitingLoadingMainDictionaries = latchForWaitingLoadingMainDictionary; mLatchForWaitingLoadingMainDictionaries = latchForWaitingLoadingMainDictionary;
ExecutorUtils.getExecutorForStaticLanguageModelUpdate().execute(new Runnable() { ExecutorUtils.getBackgroundExecutor().execute(new Runnable() {
@Override @Override
public void run() { public void run() {
doReloadUninitializedMainDictionaries( doReloadUninitializedMainDictionaries(

View File

@ -168,7 +168,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
} }
private static void asyncExecuteTaskWithLock(final Lock lock, final Runnable task) { private static void asyncExecuteTaskWithLock(final Lock lock, final Runnable task) {
ExecutorUtils.getExecutorForDynamicLanguageModelUpdate().execute(new Runnable() { ExecutorUtils.getBackgroundExecutor().execute(new Runnable() {
@Override @Override
public void run() { public void run() {
lock.lock(); lock.lock();

View File

@ -143,7 +143,7 @@ public class UserDictionaryLookup implements Closeable {
} }
// Schedule a new reload after RELOAD_DELAY_MS. // Schedule a new reload after RELOAD_DELAY_MS.
mReloadFuture = ExecutorUtils.getExecutorForDynamicLanguageModelUpdate().schedule( mReloadFuture = ExecutorUtils.getBackgroundExecutor().schedule(
mLoader, RELOAD_DELAY_MS, TimeUnit.MILLISECONDS); mLoader, RELOAD_DELAY_MS, TimeUnit.MILLISECONDS);
} }
} }
@ -186,7 +186,7 @@ public class UserDictionaryLookup implements Closeable {
// Schedule the initial load to run immediately. It's possible that the first call to // Schedule the initial load to run immediately. It's possible that the first call to
// isValidWord occurs before the dictionary has actually loaded, so it should not // isValidWord occurs before the dictionary has actually loaded, so it should not
// assume that the dictionary has been loaded. // assume that the dictionary has been loaded.
ExecutorUtils.getExecutorForDynamicLanguageModelUpdate().execute(mLoader); ExecutorUtils.getBackgroundExecutor().execute(mLoader);
// Register the observer to be notified on changes to the UserDictionary and all individual // Register the observer to be notified on changes to the UserDictionary and all individual
// items. // items.

View File

@ -21,7 +21,6 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.annotations.UsedForTesting;
import java.lang.Thread.UncaughtExceptionHandler; import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
@ -31,11 +30,10 @@ import java.util.concurrent.ThreadFactory;
*/ */
public class ExecutorUtils { public class ExecutorUtils {
private static final String STATIC_LANGUAGE_MODEL_UPDATE = "StaticLanguageModelUpdate"; private static final String TAG = "ExecutorUtils";
private static final String DYNAMIC_LANGUAGE_MODEL_UPDATE = "DynamicLanguageModelUpdate";
private static final ConcurrentHashMap<String, ScheduledExecutorService> sExecutorMap = private static final ScheduledExecutorService sExecutorService =
new ConcurrentHashMap<>(); Executors.newSingleThreadScheduledExecutor(new ExecutorFactory());
@UsedForTesting @UsedForTesting
private static ScheduledExecutorService sExecutorServiceForTests; private static ScheduledExecutorService sExecutorServiceForTests;
@ -47,37 +45,13 @@ public class ExecutorUtils {
} }
/** /**
* @return scheduled executor service used to update static language models * @return scheduled executor service used to run background tasks
*/ */
public static ScheduledExecutorService getExecutorForStaticLanguageModelUpdate() { public static ScheduledExecutorService getBackgroundExecutor() {
return getExecutor(STATIC_LANGUAGE_MODEL_UPDATE);
}
/**
* @return scheduled executor service used to update dynamic language models
*/
public static ScheduledExecutorService getExecutorForDynamicLanguageModelUpdate() {
return getExecutor(DYNAMIC_LANGUAGE_MODEL_UPDATE);
}
/**
* Gets the executor for the given id.
*/
private static ScheduledExecutorService getExecutor(final String id) {
if (sExecutorServiceForTests != null) { if (sExecutorServiceForTests != null) {
return sExecutorServiceForTests; return sExecutorServiceForTests;
} }
ScheduledExecutorService executor = sExecutorMap.get(id); return sExecutorService;
if (executor == null) {
synchronized (sExecutorMap) {
executor = sExecutorMap.get(id);
if (executor == null) {
executor = Executors.newSingleThreadScheduledExecutor(new ExecutorFactory(id));
sExecutorMap.put(id, executor);
}
}
}
return executor;
} }
/** /**
@ -85,28 +59,17 @@ public class ExecutorUtils {
*/ */
@UsedForTesting @UsedForTesting
public static void shutdownAllExecutors() { public static void shutdownAllExecutors() {
synchronized (sExecutorMap) { sExecutorService.execute(new ExecutorShutdown(sExecutorService));
for (final ScheduledExecutorService executor : sExecutorMap.values()) {
executor.execute(new ExecutorShutdown(executor));
}
sExecutorMap.clear();
}
} }
private static class ExecutorFactory implements ThreadFactory { private static class ExecutorFactory implements ThreadFactory {
private final String mThreadName;
public ExecutorFactory(final String threadName) {
mThreadName = threadName;
}
@Override @Override
public Thread newThread(final Runnable runnable) { public Thread newThread(final Runnable runnable) {
Thread thread = new Thread(runnable, mThreadName); Thread thread = new Thread(runnable, TAG);
thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override @Override
public void uncaughtException(Thread thread, Throwable ex) { public void uncaughtException(Thread thread, Throwable ex) {
Log.w(mThreadName + "-" + runnable.getClass().getSimpleName(), ex); Log.w(TAG + "-" + runnable.getClass().getSimpleName(), ex);
} }
}); });
return thread; return thread;

View File

@ -35,7 +35,7 @@ public class ExecutorUtilsTests extends AndroidTestCase {
private static final int DELAY_FOR_WAITING_TASKS_MILLISECONDS = 500; private static final int DELAY_FOR_WAITING_TASKS_MILLISECONDS = 500;
public void testExecute() { public void testExecute() {
final ExecutorService executor = ExecutorUtils.getExecutorForDynamicLanguageModelUpdate(); final ExecutorService executor = ExecutorUtils.getBackgroundExecutor();
final AtomicInteger v = new AtomicInteger(0); final AtomicInteger v = new AtomicInteger(0);
for (int i = 0; i < NUM_OF_TASKS; ++i) { for (int i = 0; i < NUM_OF_TASKS; ++i) {
executor.execute(new Runnable() { executor.execute(new Runnable() {