1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.inputmethod.latin.utils;
18 
19 import com.android.inputmethod.annotations.UsedForTesting;
20 
21 import java.util.concurrent.ConcurrentHashMap;
22 import java.util.concurrent.ExecutorService;
23 import java.util.concurrent.Executors;
24 import java.util.concurrent.ThreadFactory;
25 
26 /**
27  * Utilities to manage executors.
28  */
29 public class ExecutorUtils {
30     private static final ConcurrentHashMap<String, ExecutorService> sExecutorMap =
31             new ConcurrentHashMap<>();
32 
33     private static class ThreadFactoryWithId implements ThreadFactory {
34         private final String mId;
35 
ThreadFactoryWithId(final String id)36         public ThreadFactoryWithId(final String id) {
37             mId = id;
38         }
39 
40         @Override
newThread(final Runnable r)41         public Thread newThread(final Runnable r) {
42             return new Thread(r, "Executor - " + mId);
43         }
44     }
45 
46     /**
47      * Gets the executor for the given id.
48      */
getExecutor(final String id)49     public static ExecutorService getExecutor(final String id) {
50         ExecutorService executor = sExecutorMap.get(id);
51         if (executor == null) {
52             synchronized(sExecutorMap) {
53                 executor = sExecutorMap.get(id);
54                 if (executor == null) {
55                     executor = Executors.newSingleThreadExecutor(new ThreadFactoryWithId(id));
56                     sExecutorMap.put(id, executor);
57                 }
58             }
59         }
60         return executor;
61     }
62 
63     /**
64      * Shutdowns all executors and removes all executors from the executor map for testing.
65      */
66     @UsedForTesting
shutdownAllExecutors()67     public static void shutdownAllExecutors() {
68         synchronized(sExecutorMap) {
69             for (final ExecutorService executor : sExecutorMap.values()) {
70                 executor.execute(new Runnable() {
71                     @Override
72                     public void run() {
73                         executor.shutdown();
74                         sExecutorMap.remove(executor);
75                     }
76                 });
77             }
78         }
79     }
80 }
81