1.任务优先级的概念
为保证应用有更好的响应性,我们需要设计任务的优先级。在UI线程上运行的任务默认以高优先级运行,如果某个任务无需等待结果,则可以用低优先级。在分发任务时可以指定任务的优先级,由同一个任务分发器分发出的任务具有相同的优先级。
2.TaskDispatcher
TaskDispatcher是一个任务分发器,它是Ability分发任务的基本接口,隐藏任务所在线程的实现细节。TaskDispatcher具有多种实现,每种实现对应不同的任务分发器
- GlobalTaskDispatcher
全局并发任务分发器,由Ability执行getGlobalTaskDispatcher()获取。适用于任务之间没有联系的情况。一个应用只有一个GlobalTaskDispatcher,它在程序结束时才被销毁。
for (int i = 0; i < 1000; i++) {
//创建GlobalTaskDispatcher
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
//执行异步任务
globalTaskDispatcher.asyncDispatch(new Runnable() {
@Override
public void run() {
HiLog.error(LABEL_LOG, "getGlobalTaskDispatcher ThreadName:" + Thread.currentThread().getName()
+ "--ThreadId:" + Thread.currentThread().getId());
HiLog.error(LABEL_LOG, "globalTaskDispatcher ID:" + globalTaskDispatcher.hashCode());
}
});
}
输出结果:
结论:
1.GlobalTaskDispatcher中的任务执行是在子线程中执行的,而且是从线程池中创建线程来执行,所以通过GlobalTaskDispatcher来执行的任务是可以进行耗时操作的,但是不能刷新UI。
2.GlobalTaskDispatcher的对象在全局是唯一的,通过不断创建GlobalTaskDispatcher,获取到的hashCode都是唯一的。
3.GlobalTaskDispatcher的线程池核心线程数是一个固定值,我自己测试为32,这个可能跟主机CPU有关系,也可能跟代码实现逻辑有关系,需要进一步等开源代码后验证。
- ParallelTaskDispatcher
并发任务分发器,由Ability执行createParallelTaskDispatcher()创建并返回。与GlobalTaskDispatcher不同的是,ParallelTaskDispatcher不具有全局唯一性,可以创建多个。开发者在创建或销毁dispatcher时,需要持有对应的对象引用
String dispatcherName = "parallelTaskDispatcher";
TaskDispatcher parallelTaskDispatcher = createParallelTaskDispatcher(dispatcherName, TaskPriority.DEFAULT);
parallelTaskDispatcher.asyncDispatch(new Runnable() {
@Override
public void run() {
HiLog.error(LABEL_LOG, "parallelTaskDispatcher threadName:" + Thread.currentThread().getName()
+ "--ThreadId:" + Thread.currentThread().getId());
}
});
//输出结果:
//parallelTaskDispatcher threadName:PoolThread-1--ThreadId:34627
同样该任务分发器的任务执行在子线程中。
- SerialTaskDispatcher
串行任务分发器,由Ability执行createSerialTaskDispatcher()创建并返回。由该分发器分发的所有的任务都是按顺序执行,但是执行这些任务的线程并不是固定的。如果要执行并行任务,应使用ParallelTaskDispatcher或者GlobalTaskDispatcher,而不是创建多个SerialTaskDispatcher。如果任务之间没有依赖,应使用GlobalTaskDispatcher来实现。它的创建和销毁由开发者自己管理,开发者在使用期间需要持有该对象引用。
String dispatcherName = "serialTaskDispatcher";
TaskDispatcher serialTaskDispatcher = createSerialTaskDispatcher(dispatcherName, TaskPriority.DEFAULT);
for (int i = 0; i < 1000; i++) {
//执行异步任务
int finalI = i;
serialTaskDispatcher.asyncDispatch(new Runnable() {
@Override
public void run() {
HiLog.error(LABEL_LOG, "serialTaskDispatcher 执行第" + finalI + " ThreadName:" + Thread.currentThread().getName()
+ "--ThreadId:" + Thread.currentThread().getId());
HiLog.error(LABEL_LOG, "serialTaskDispatcher ID:" + serialTaskDispatcher.hashCode());
}
});
}
也就是说该任务分发器执行的任务会按顺序执行,但是执行的线程不是唯一的,会从线程池里边去取,执行不同的任务可能取到的线程不一致。- SpecTaskDispatcher
专有任务分发器,绑定到专有线程上的任务分发器。目前已有的专有线程为UI线程,通过UITaskDispatcher进行任务分发。
UITaskDispatcher:绑定到应用主线程的专有任务分发器, 由Ability执行getUITaskDispatcher()创建并返回。 由该分发器分发的所有的任务都是在主线程上按顺序执行,它在应用程序结束时被销毁。
getUITaskDispatcher().asyncDispatch(new Runnable() {
@Override
public void run() {
HiLog.error(LABEL_LOG, "getUITaskDispatcher threadName:" + Thread.currentThread().getName()
+ "--ThreadId:" + Thread.currentThread().getId());
}
});
getMainTaskDispatcher().asyncDispatch(new Runnable() {
@Override
public void run() {
HiLog.error(LABEL_LOG, "getMainTaskDispatcher threadName:" + Thread.currentThread().getName()
+ "--ThreadId:" + Thread.currentThread().getId());
}
});
输出结果:getMainTaskDispatcher()和getUITaskDispatcher()的任务都是执行在主线程中,所以在这两个分发器中执行的任务不能进行耗时操作,但是可以进行更新UI操作。