16
16
17
17
import android .os .AsyncTask ;
18
18
import com .google .android .gms .tasks .TaskExecutors ;
19
- import java .util .Queue ;
20
- import java .util .concurrent .ConcurrentLinkedQueue ;
21
19
import java .util .concurrent .Executor ;
22
- import java .util .concurrent .atomic .AtomicInteger ;
23
20
24
21
/** Helper class for executors. */
25
22
public final class Executors {
26
23
/**
27
24
* The maximum number of tasks we submit to AsyncTask.THREAD_POOL_EXECUTOR.
28
25
*
29
- * <p>The limit is based on the number of core threads spun by THREAD_POOL_EXECUTOR and addresses
30
- * its queue size limit of 120 pending tasks.
26
+ * <p>The limit is based on the number of core threads spun by THREAD_POOL_EXECUTOR and is well
27
+ * below the queue size limit of 120 pending tasks. Limiting our usage of the THREAD_POOL_EXECUTOR
28
+ * allows other users to schedule their own operations on the shared THREAD_POOL_EXECUTOR.
31
29
*/
32
- private static final int MAXIMUM_CONCURRENT_BACKGROUND_TASKS = 4 ;
30
+ private static final int ASYNC_THREAD_POOL_MAXIMUM_CONCURRENCY = 4 ;
33
31
34
32
/**
35
33
* The default executor for user visible callbacks. It is an executor scheduling callbacks on
@@ -40,38 +38,10 @@ public final class Executors {
40
38
/** An executor that executes the provided runnable immediately on the current thread. */
41
39
public static final Executor DIRECT_EXECUTOR = Runnable ::run ;
42
40
43
- /**
44
- * An executor that runs tasks in parallel on Android's AsyncTask.THREAD_POOL_EXECUTOR.
45
- *
46
- * <p>Unlike the main THREAD_POOL_EXECUTOR, this executor manages its own queue of tasks and can
47
- * handle an unbounded number of pending tasks.
48
- */
41
+ /** An executor that runs tasks in parallel on Android's AsyncTask.THREAD_POOL_EXECUTOR. */
49
42
public static final Executor BACKGROUND_EXECUTOR =
50
- new Executor () {
51
- AtomicInteger activeRunnerCount = new AtomicInteger (0 );
52
- Queue <Runnable > pendingTasks = new ConcurrentLinkedQueue <>();
53
-
54
- @ Override
55
- public void execute (Runnable command ) {
56
- pendingTasks .add (command );
57
-
58
- if (activeRunnerCount .get () < MAXIMUM_CONCURRENT_BACKGROUND_TASKS ) {
59
- // Note that the runner count could temporarily exceed
60
- // MAXIMUM_CONCURRENT_BACKGROUND_TASKS if this is code path was executed in parallel.
61
- // While undesired, this would merely queue another task on THREAD_POOL_EXECUTOR,
62
- // and we are unlikely to hit the 120 pending task limit.
63
- activeRunnerCount .incrementAndGet ();
64
- AsyncTask .THREAD_POOL_EXECUTOR .execute (
65
- () -> {
66
- Runnable r ;
67
- while ((r = pendingTasks .poll ()) != null ) {
68
- r .run ();
69
- }
70
- activeRunnerCount .decrementAndGet ();
71
- });
72
- }
73
- }
74
- };
43
+ new ThrottledForwardingExecutor (
44
+ ASYNC_THREAD_POOL_MAXIMUM_CONCURRENCY , AsyncTask .THREAD_POOL_EXECUTOR );
75
45
76
46
private Executors () {
77
47
// Private constructor to prevent initialization
0 commit comments