如何在安卓系统中使用 ThreadPoolExecutor?
原文:https://www . geesforgeks . org/how-用法-threadpoolexecutor-in-Android/
任务队列包含等待池中任何空闲线程执行的作业。生产者向队列贡献任务,而工作线程充当消费者,每当空闲线程准备进行新的后台操作时,就从队列中消费作业。
但是在我们深入之前,安卓中到底什么是线程池?
它是一个线程池器,负责处理所有与线程相关的任务,尽管线程的适当数量与线程池器的实现方式成正比。
线程池执行器
线程池执行器使用线程池中的一个线程来完成特定的作业。
Java 语言(一种计算机语言,尤用于创建网站)
ThreadPoolExecutor gfgPoolExecutor
= new ThreadPoolExecutor(
int mainPoolSize,
long keepAliveTime,
int maximumPoolSize,
TimeUnit unit,
BlockingQueue<Runnable> workQueue
);
你可能想知道所有这些价值观指的是什么,对吗?
- mainPoolSize :始终保持在池中的线程数。一开始池中没有线程。但是,当作业添加到队列中时,会生成新的线程。如果有空闲线程,但线程数小于主池大小,将继续生成新线程。
- keepAliveTime: 当线程数超过核心线程数时,非核心线程(额外空闲线程)将等待新作业,如果在此参数指示的时间段内没有得到新作业,将终止。
- maximumPoolSize: 可以同时在池中的最大线程数。如果这超过了主池大小,并且当前线程数超过了主池大小,则只有当队列为空时,才会生成额外的工作线程。
- 单位:【keepAliveTime 的时间单位。
- 工作队列:任务队列,只保存可以执行的作业。这将是一个阻塞队列。
问题出现了,
为什么你会在安卓或 Java 应用中使用线程池执行器?
它是一个强大的任务执行框架,因为它允许任务队列插入、任务取消和任务优先级排序。它通过管理线程池中预定数量的线程来降低与线程创建相关的开销。
极客提示:不同线程池可用的线程数量可能因您的需求而异。
安卓系统如何使用线程池
步骤#1:创建一个 GfGThreadMechanism
Java 语言(一种计算机语言,尤用于创建网站)
public class GfGThreadMechanism implements ThreadFactory {
private final int gfgPriority;
public PriorityThreadFactory(int threadPriority) {
gfgPriority = threadPriority;
}
@Override
public Thread newThread(final Runnable gfgRunner) {
Runnable wrapperRunnable = new Runnable() {
@Override
public void run() {
try {
Process.setThreadPriority(gfgPriority);
} catch (Throwable t) {
}
gfgRunner.run();
}
};
return new Thread(wrapperRunnable);
}
}
步骤 2: 创建主线程执行器
Java 语言(一种计算机语言,尤用于创建网站)
public class MasterThreadExecutor implements Executor {
private final Handler gfgHandler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable runnable) {
gfgHandler.post(runnable);
}
}
步骤#3:创建一个单独的类来执行
Java 语言(一种计算机语言,尤用于创建网站)
public class gfgExecutor{
// Number of threads, are being set here.
public static final int NUMBER_OF_THREADS = Runtime.getRuntime().availableProcessors();
// Setting and Monitoring BG Tasks
private final ThreadPoolExecutor gfgTasks;
// another executor for handling light feather tasks
private final ThreadPoolExecutor gfgFeatherTasks;
// the thread pool which manages the heavy tasks
private final Executor publicExecutor;
// an instance of DefaultExecutorSupplier
private static DefaultExecutorSupplier gfgInstance;
// returns the instance of DefaultExecutorSupplier
public static DefaultExecutorSupplier getInstance() {
if (gfgInstance == null) {
synchronized(DefaultExecutorSupplier.class){
gfgInstance = new DefaultExecutorSupplier();
}
return gfgInstance;
}
// Main Magic Goes Here
private DefaultExecutorSupplier() {
// setting the thread factory
ThreadFactory backgroundPriorityThreadFactory = new
PriorityThreadFactory(Process.THREAD_PRIORITY_BACKGROUND);
// setting the thread pool executor for gfgTasks;
gfgTasks = new ThreadPoolExecutor(
NUMBER_OF_THREADS * 2,
NUMBER_OF_THREADS * 2,
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(),
backgroundPriorityThreadFactory
);
// setting the thread pool executor for gfgFeatherTasks;
gfgFeatherTasks = new ThreadPoolExecutor(
NUMBER_OF_THREADS * 2,
NUMBER_OF_THREADS * 2,
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(),
backgroundPriorityThreadFactory
);
// setting the thread pool executor for gfgExecutor;
gfgExecutor = new MainThreadExecutor();
}
// thread pool which returns the BG task
public ThreadPoolExecutor forBackgroundTasks() {
return gfgTasks;
}
// similar to the return above, but for feather tasks
public ThreadPoolExecutor forLightWeightBackgroundTasks() {
return gfgFeatherTasks;
}
// similar to the return above, but for heavy tasks
public Executor forMainThreadTasks() {
return mMainThreadExecutor;
}
}
现在在任何活动中使用这个类,你都准备好了!
你如何区分任务的优先级?
假设一个队列中有 10 个作业,线程池只能处理 4 个线程。因为线程池一次只能执行四个活动,所以我们优先考虑新作业。但是假设我们要求我们放入队列中的最后一个作业首先完成。我们需要赋予该作业立即优先级,这样当线程从队列中获得新任务时,它会首先运行它(因为它具有最高优先级)。要对作业进行优先级排序,我们必须首先构建一个线程池执行器。
创建优先级枚举:
Java 语言(一种计算机语言,尤用于创建网站)
// The different urgency levels
public enum Urgency {
// Lowest urgency level
LOW,
// Medium urgency level
MEDIUM,
// Highest urgency level
HIGH,
// Highest urgency level,
// even up from the previous
IMMEDIATE;
}
然后,我们为紧急情况创建一个可运行的:
Java 语言(一种计算机语言,尤用于创建网站)
public class UrgencyRunnable implements Runnable {
private final Priority gfgUrgency;
public PriorityRunnable(Priority gfgUrgency) {
this.gfgUrgency = gfgUrgency;
}
@Override
public void run() {
// your code, or leave blank.
}
public Priority gfgUrgency() {
return gfgUrgency;
}
}
通过扩展线程池执行器使线程池执行器优先。
必须创建优先级未来任务,它将实现。
Java 语言(一种计算机语言,尤用于创建网站)
public class UrgencyExecutor extends ThreadPoolExecutor {
public PriorityThreadPoolExecutor(int gfgPool, int gfgMax, long gfgTime,
TimeUnit unit, ThreadFactory threadFactory) {
super(gfgPool, gfgMax, gfgTime, unit,new PriorityBlockingQueue<Runnable>(), threadFactory);
}
@Override
public gfgTask<?> submit(Runnable gfgBackTask) {
PriorityFutureTask gfgTask = new PriorityFutureTask((PriorityRunnable) task);
execute(gfgTask);
return gfgTask;
}
private static final class PriorityFutureTask extends FutureTask<PriorityRunnable>
implements Comparable<gfgTask> {
private final PriorityRunnable priorityRunnable;
public gfgTask(PriorityRunnable priorityRunnable) {
super(priorityRunnable, null);
this.priorityRunnable = priorityRunnable;
}
@Override
public int compareTo(gfgTask other) {
Priority gfg1 = priorityRunnable.getPriority();
Priority gfg2 = other.priorityRunnable.getPriority();
return gfg2.ordinal() - gfg1.ordinal();
}
}
}
首先,在缺省执行器供应商中使用优先级线程池执行器,而不是线程池执行器,如下所示:
Java 语言(一种计算机语言,尤用于创建网站)
public class DefaultExecutorSupplier{
private final PriorityThreadPoolExecutor gfgBackTask;
private DefaultExecutorSupplier() {
gfgBackTask = new PriorityThreadPoolExecutor(
NUMBER_OF_THREADS * 4,
NUMBER_OF_THREADS * 3,
50L,
TimeUnit.SECONDS,
backgroundPriorityThreadFactory
);
}
}
下面是一个我们如何将一项工作列为低优先级的例子:
Java 语言(一种计算机语言,尤用于创建网站)
// Doing at LOW
public void doingAtLowUrgency(){
DefaultExecutorSupplier.getInstance().forBackgroundTasks()
.submit(new PriorityRunnable(Priority.LOW) {
@Override
public void run() {
// some back tasks go here
}
});
}
结论
可以用这种方式对任务进行优先级排序。上述实现也适用于任何 JAVA 应用程序。希望这篇文章为你扫清了空气!
版权属于:月萌API www.moonapi.com,转载请注明出处