diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index d6e6656ab5fd21baaad73312545b8856044493f1..36a02669d3240dfda6cee141a5cfb87d6531a7ba 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -468,7 +468,9 @@ public class DictionaryFacilitator {
         // We don't add words with 0-frequency (assuming they would be profanity etc.).
         final boolean isValid = maxFreq > 0;
         UserHistoryDictionary.addToDictionary(userHistoryDictionary, prevWordsInfo, secondWord,
-                isValid, timeStampInSeconds, mDistracterFilter);
+                isValid, timeStampInSeconds,
+                new DistracterFilterCheckingIsInDictionary(
+                        mDistracterFilter, userHistoryDictionary));
     }
 
     private void removeWord(final String dictName, final String word) {
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 5808b9e4e8fbfadd0bb234a19061d5d4731301ef..c11a220a4f0e97ce4ff2a569af898f7f3fefdff5 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -38,6 +38,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
+import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -163,9 +164,31 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
     }
 
     private void asyncExecuteTaskWithLock(final Lock lock, final Runnable task) {
+        asyncPreCheckAndExecuteTaskWithLock(lock, null /* preCheckTask */, task);
+    }
+
+    private void asyncPreCheckAndExecuteTaskWithWriteLock(
+            final Callable<Boolean> preCheckTask, final Runnable task) {
+        asyncPreCheckAndExecuteTaskWithLock(mLock.writeLock(), preCheckTask, task);
+
+    }
+
+    // Execute task with lock when the result of preCheckTask is true or preCheckTask is null.
+    private void asyncPreCheckAndExecuteTaskWithLock(final Lock lock,
+            final Callable<Boolean> preCheckTask, final Runnable task) {
         ExecutorUtils.getExecutor(mDictName).execute(new Runnable() {
             @Override
             public void run() {
+                if (preCheckTask != null) {
+                    try {
+                        if (!preCheckTask.call().booleanValue()) {
+                            return;
+                        }
+                    } catch (final Exception e) {
+                        Log.e(TAG, "The pre check task throws an exception.", e);
+                        return;
+                    }
+                }
                 lock.lock();
                 try {
                     task.run();
@@ -278,22 +301,25 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
             final boolean isBlacklisted, final int timestamp,
             final DistracterFilter distracterFilter) {
         reloadDictionaryIfRequired();
-        asyncExecuteTaskWithWriteLock(new Runnable() {
-            @Override
-            public void run() {
-                if (mBinaryDictionary == null) {
-                    return;
-                }
-                if (distracterFilter.isDistracterToWordsInDictionaries(
-                        PrevWordsInfo.EMPTY_PREV_WORDS_INFO, word, mLocale)) {
-                    // The word is a distracter.
-                    return;
-                }
-                runGCIfRequiredLocked(true /* mindsBlockByGC */);
-                addUnigramLocked(word, frequency, shortcutTarget, shortcutFreq,
-                        isNotAWord, isBlacklisted, timestamp);
-            }
-        });
+        asyncPreCheckAndExecuteTaskWithWriteLock(
+                new Callable<Boolean>() {
+                    @Override
+                    public Boolean call() throws Exception {
+                        return !distracterFilter.isDistracterToWordsInDictionaries(
+                                PrevWordsInfo.EMPTY_PREV_WORDS_INFO, word, mLocale);
+                    }
+                },
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        if (mBinaryDictionary == null) {
+                            return;
+                        }
+                        runGCIfRequiredLocked(true /* mindsBlockByGC */);
+                        addUnigramLocked(word, frequency, shortcutTarget, shortcutFreq,
+                                isNotAWord, isBlacklisted, timestamp);
+                    }
+                });
     }
 
     protected void addUnigramLocked(final String word, final int frequency,