From f9e2d271ca101a53a6aac772ca770242805793ef Mon Sep 17 00:00:00 2001 From: Dan Zivkovic Date: Mon, 9 Mar 2015 13:22:56 -0700 Subject: [PATCH] Use a single background executor. Bug 19625976. Change-Id: Ia03f440a31b059b5af42d162e1145330bf7b5ddf --- .../latin/ContactsContentObserver.java | 2 +- .../latin/DictionaryFacilitatorImpl.java | 2 +- .../latin/ExpandableBinaryDictionary.java | 2 +- .../spellcheck/UserDictionaryLookup.java | 4 +- .../latin/utils/ExecutorUtils.java | 55 +++---------------- .../latin/utils/ExecutorUtilsTests.java | 2 +- 6 files changed, 15 insertions(+), 52 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/ContactsContentObserver.java b/java/src/com/android/inputmethod/latin/ContactsContentObserver.java index e45681bd7..04c1cf333 100644 --- a/java/src/com/android/inputmethod/latin/ContactsContentObserver.java +++ b/java/src/com/android/inputmethod/latin/ContactsContentObserver.java @@ -56,7 +56,7 @@ public class ContactsContentObserver implements Runnable { mContentObserver = new ContentObserver(null /* handler */) { @Override public void onChange(boolean self) { - ExecutorUtils.getExecutorForDynamicLanguageModelUpdate() + ExecutorUtils.getBackgroundExecutor() .execute(ContactsContentObserver.this); } }; diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java index 7ad2a9f7d..6080900a1 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java @@ -444,7 +444,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { final Locale[] locales, final DictionaryInitializationListener listener) { final CountDownLatch latchForWaitingLoadingMainDictionary = new CountDownLatch(1); mLatchForWaitingLoadingMainDictionaries = latchForWaitingLoadingMainDictionary; - ExecutorUtils.getExecutorForStaticLanguageModelUpdate().execute(new Runnable() { + ExecutorUtils.getBackgroundExecutor().execute(new Runnable() { @Override public void run() { doReloadUninitializedMainDictionaries( diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index b0fb91bec..138a2ea5c 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -168,7 +168,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } private static void asyncExecuteTaskWithLock(final Lock lock, final Runnable task) { - ExecutorUtils.getExecutorForDynamicLanguageModelUpdate().execute(new Runnable() { + ExecutorUtils.getBackgroundExecutor().execute(new Runnable() { @Override public void run() { lock.lock(); diff --git a/java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java b/java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java index 856f16a53..6ab741ca1 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java @@ -143,7 +143,7 @@ public class UserDictionaryLookup implements Closeable { } // Schedule a new reload after RELOAD_DELAY_MS. - mReloadFuture = ExecutorUtils.getExecutorForDynamicLanguageModelUpdate().schedule( + mReloadFuture = ExecutorUtils.getBackgroundExecutor().schedule( 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 // isValidWord occurs before the dictionary has actually loaded, so it should not // 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 // items. diff --git a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java index c533a6273..b21538caa 100644 --- a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java @@ -21,7 +21,6 @@ import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; import java.lang.Thread.UncaughtExceptionHandler; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; @@ -31,11 +30,10 @@ import java.util.concurrent.ThreadFactory; */ public class ExecutorUtils { - private static final String STATIC_LANGUAGE_MODEL_UPDATE = "StaticLanguageModelUpdate"; - private static final String DYNAMIC_LANGUAGE_MODEL_UPDATE = "DynamicLanguageModelUpdate"; + private static final String TAG = "ExecutorUtils"; - private static final ConcurrentHashMap sExecutorMap = - new ConcurrentHashMap<>(); + private static final ScheduledExecutorService sExecutorService = + Executors.newSingleThreadScheduledExecutor(new ExecutorFactory()); @UsedForTesting 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() { - 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) { + public static ScheduledExecutorService getBackgroundExecutor() { if (sExecutorServiceForTests != null) { return sExecutorServiceForTests; } - ScheduledExecutorService executor = sExecutorMap.get(id); - if (executor == null) { - synchronized (sExecutorMap) { - executor = sExecutorMap.get(id); - if (executor == null) { - executor = Executors.newSingleThreadScheduledExecutor(new ExecutorFactory(id)); - sExecutorMap.put(id, executor); - } - } - } - return executor; + return sExecutorService; } /** @@ -85,28 +59,17 @@ public class ExecutorUtils { */ @UsedForTesting public static void shutdownAllExecutors() { - synchronized (sExecutorMap) { - for (final ScheduledExecutorService executor : sExecutorMap.values()) { - executor.execute(new ExecutorShutdown(executor)); - } - sExecutorMap.clear(); - } + sExecutorService.execute(new ExecutorShutdown(sExecutorService)); } private static class ExecutorFactory implements ThreadFactory { - private final String mThreadName; - - public ExecutorFactory(final String threadName) { - mThreadName = threadName; - } - @Override public Thread newThread(final Runnable runnable) { - Thread thread = new Thread(runnable, mThreadName); + Thread thread = new Thread(runnable, TAG); thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread thread, Throwable ex) { - Log.w(mThreadName + "-" + runnable.getClass().getSimpleName(), ex); + Log.w(TAG + "-" + runnable.getClass().getSimpleName(), ex); } }); return thread; diff --git a/tests/src/com/android/inputmethod/latin/utils/ExecutorUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/ExecutorUtilsTests.java index 3b1e43ed8..d722151cf 100644 --- a/tests/src/com/android/inputmethod/latin/utils/ExecutorUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/ExecutorUtilsTests.java @@ -35,7 +35,7 @@ public class ExecutorUtilsTests extends AndroidTestCase { private static final int DELAY_FOR_WAITING_TASKS_MILLISECONDS = 500; public void testExecute() { - final ExecutorService executor = ExecutorUtils.getExecutorForDynamicLanguageModelUpdate(); + final ExecutorService executor = ExecutorUtils.getBackgroundExecutor(); final AtomicInteger v = new AtomicInteger(0); for (int i = 0; i < NUM_OF_TASKS; ++i) { executor.execute(new Runnable() {