• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.bumptech.glide.load.engine.executor;
2 
3 import java.util.concurrent.FutureTask;
4 import java.util.concurrent.PriorityBlockingQueue;
5 import java.util.concurrent.RunnableFuture;
6 import java.util.concurrent.ThreadFactory;
7 import java.util.concurrent.ThreadPoolExecutor;
8 import java.util.concurrent.TimeUnit;
9 import java.util.concurrent.atomic.AtomicInteger;
10 
11 /**
12  * A FIFO priority {@link ThreadPoolExecutor} that prioritizes submitted {@link Runnable}s by assuming they implement
13  * {@link Prioritized}. {@link Prioritized} runnables that return lower values for {@link Prioritized#getPriority()}
14  * will be executed before those that return higher values. Priorities only apply when multiple items are queued at the
15  * same time. Runnables with the same priority will be executed in FIFO order.
16  */
17 public class FifoPriorityThreadPoolExecutor extends ThreadPoolExecutor {
18     AtomicInteger ordering = new AtomicInteger();
19 
20     /**
21      * Constructor to build a fixed thread pool with the given pool size using
22      * {@link com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor.DefaultThreadFactory}.
23      *
24      * @param poolSize The number of threads.
25      */
FifoPriorityThreadPoolExecutor(int poolSize)26     public FifoPriorityThreadPoolExecutor(int poolSize) {
27         this(poolSize, poolSize, 0, TimeUnit.MILLISECONDS, new DefaultThreadFactory());
28     }
29 
FifoPriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAlive, TimeUnit timeUnit, ThreadFactory threadFactory)30     public FifoPriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAlive, TimeUnit timeUnit,
31             ThreadFactory threadFactory) {
32         super(corePoolSize, maximumPoolSize, keepAlive, timeUnit, new PriorityBlockingQueue<Runnable>(), threadFactory);
33     }
34 
35     @Override
newTaskFor(Runnable runnable, T value)36     protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
37         return new LoadTask<T>(runnable, value, ordering.getAndIncrement());
38     }
39 
40     /**
41      * A {@link java.util.concurrent.ThreadFactory} that builds threads with priority
42      * {@link android.os.Process#THREAD_PRIORITY_BACKGROUND}.
43      */
44     public static class DefaultThreadFactory implements ThreadFactory {
45         int threadNum = 0;
46         @Override
newThread(Runnable runnable)47         public Thread newThread(Runnable runnable) {
48             final Thread result = new Thread(runnable, "fifo-pool-thread-" + threadNum) {
49                 @Override
50                 public void run() {
51                     android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
52                     super.run();
53                 }
54             };
55             threadNum++;
56             return result;
57         }
58     }
59 
60     // Visible for testing.
61     static class LoadTask<T> extends FutureTask<T> implements Comparable<LoadTask<?>> {
62         private final int priority;
63         private final int order;
64 
LoadTask(Runnable runnable, T result, int order)65         public LoadTask(Runnable runnable, T result, int order) {
66             super(runnable, result);
67             if (!(runnable instanceof Prioritized)) {
68                 throw new IllegalArgumentException("FifoPriorityThreadPoolExecutor must be given Runnables that "
69                         + "implement Prioritized");
70             }
71             priority = ((Prioritized) runnable).getPriority();
72             this.order = order;
73         }
74 
75         @SuppressWarnings("unchecked")
76         @Override
equals(Object o)77         public boolean equals(Object o) {
78             if (o instanceof LoadTask) {
79                 LoadTask<Object> other = (LoadTask<Object>) o;
80                 return order == other.order && priority == other.priority;
81             }
82             return false;
83         }
84 
85         @Override
hashCode()86         public int hashCode() {
87             int result = priority;
88             result = 31 * result + order;
89             return result;
90         }
91 
92         @Override
compareTo(LoadTask<?> loadTask)93         public int compareTo(LoadTask<?> loadTask) {
94             int result = priority - loadTask.priority;
95             if (result == 0) {
96                 result = order - loadTask.order;
97             }
98             return result;
99         }
100     }
101 }
102