diff options
author | 2015-02-17 15:12:05 -0800 | |
---|---|---|
committer | 2015-02-19 11:40:57 -0800 | |
commit | 0b03f13cabec84d2d841fde47ce9fec0d531b6a1 (patch) | |
tree | 5cc14dea6693025f25d279dd59140c04d0d7495f /java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java | |
parent | 95711bfcee07d848883316cf07439408f5b332a1 (diff) | |
download | latinime-0b03f13cabec84d2d841fde47ce9fec0d531b6a1.tar.gz latinime-0b03f13cabec84d2d841fde47ce9fec0d531b6a1.tar.xz latinime-0b03f13cabec84d2d841fde47ce9fec0d531b6a1.zip |
Sanitize the usage of executors.
There should be 1 executor each for static and dynamic language models.
This prevents too many dynamic LM updates from running in parallel,
competing for resources.
Change-Id: I8ec439e0ea2d92fba275bc20a0b8c9193346a0c1
Diffstat (limited to 'java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java | 88 |
1 files changed, 67 insertions, 21 deletions
diff --git a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java index 50be16072..c533a6273 100644 --- a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java @@ -16,10 +16,12 @@ package com.android.inputmethod.latin.utils; +import android.util.Log; + import com.android.inputmethod.annotations.UsedForTesting; +import java.lang.Thread.UncaughtExceptionHandler; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; @@ -28,33 +30,49 @@ import java.util.concurrent.ThreadFactory; * Utilities to manage executors. */ public class ExecutorUtils { - static final ConcurrentHashMap<String, ScheduledExecutorService> sExecutorMap = + + private static final String STATIC_LANGUAGE_MODEL_UPDATE = "StaticLanguageModelUpdate"; + private static final String DYNAMIC_LANGUAGE_MODEL_UPDATE = "DynamicLanguageModelUpdate"; + + private static final ConcurrentHashMap<String, ScheduledExecutorService> sExecutorMap = new ConcurrentHashMap<>(); - private static class ThreadFactoryWithId implements ThreadFactory { - private final String mId; + @UsedForTesting + private static ScheduledExecutorService sExecutorServiceForTests; - public ThreadFactoryWithId(final String id) { - mId = id; - } + @UsedForTesting + public static void setExecutorServiceForTests( + final ScheduledExecutorService executorServiceForTests) { + sExecutorServiceForTests = executorServiceForTests; + } - @Override - public Thread newThread(final Runnable r) { - return new Thread(r, "Executor - " + mId); - } + /** + * @return scheduled executor service used to update static language models + */ + 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. */ - public static ScheduledExecutorService getExecutor(final String id) { + private static ScheduledExecutorService getExecutor(final String id) { + 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 ThreadFactoryWithId(id)); + executor = Executors.newSingleThreadScheduledExecutor(new ExecutorFactory(id)); sExecutorMap.put(id, executor); } } @@ -69,14 +87,42 @@ public class ExecutorUtils { public static void shutdownAllExecutors() { synchronized (sExecutorMap) { for (final ScheduledExecutorService executor : sExecutorMap.values()) { - executor.execute(new Runnable() { - @Override - public void run() { - executor.shutdown(); - sExecutorMap.remove(executor); - } - }); + executor.execute(new ExecutorShutdown(executor)); } + sExecutorMap.clear(); + } + } + + 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.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread thread, Throwable ex) { + Log.w(mThreadName + "-" + runnable.getClass().getSimpleName(), ex); + } + }); + return thread; + } + } + + private static class ExecutorShutdown implements Runnable { + private final ScheduledExecutorService mExecutor; + + public ExecutorShutdown(final ScheduledExecutorService executor) { + mExecutor = executor; + } + + @Override + public void run() { + mExecutor.shutdown(); } } } |