什么是线程管理
不同应用在各自独立的进程中运行。当应用以任何形式启动时,系统为其创建进程,该进程将持续运行。当进程完成当前任务处于等待状态,且系统资源不足时,系统自动回收。
在启动应用时,系统会为该应用创建一个称为“主线程”的执行线程。该线程随着应用创建或消失,是应用的核心线程。UI 界面的显示和更新等操作,都是在主线程上进行。主线程又称 UI 线程,默认情况下,所有的操作都是在主线程上执行。如果需要执行比较耗时的任务(如下载文件、查询数据库),可创建其他线程来处理。
适用场景
如果应用的业务逻辑比较复杂,可能需要创建多个线程来执行多个任务。这种情况下,代码复杂难以维护,任务与线程的交互也会更加繁杂。要解决此问题,开发者可以使用“TaskDispatcher”来分发不同的任务。
接口说明
TaskDispatcher 是一个任务分发器,它是 Ability 分发任务的基本接口,隐藏任务所在线程的实现细节。在 UI 线程上运行的任务默认以高优先级运行,如果某个任务无需等待结果,则可以用低优先级。表 1 线程优先级介绍
系统提供的任务分发器有 GlobalTaskDispatcher、ParallelTaskDispatcher、SerialTaskDispatcher 、SpecTaskDispatcher。
GlobalTaskDispatcher 全局并发任务分发器,由 Ability 执行 getGlobalTaskDispatcher()获取。适用于任务之间没有联系的情况。一个应用只有一个 GlobalTaskDispatcher,它在程序结束时才被销毁。
ParallelTaskDispatcher 并发任务分发器,由 Ability 执行 createParallelTaskDispatcher()创建并返回。与 GlobalTaskDispatcher 不同的是,ParallelTaskDispatcher 不具有全局唯一性,可以创建多个。开发者在创建或销毁 dispatcher 时,需要持有对应的对象引用 。
SerialTaskDispatcher 串行任务分发器,由 Ability 执行 createSerialTaskDispatcher()创建并返回。由该分发器分发的所有的任务都是按顺序执行,但是执行这些任务的线程并不是固定的。如果要执行并行任务,应使用 ParallelTaskDispatcher 或者 GlobalTaskDispatcher,而不是创建多个 SerialTaskDispatcher。如果任务之间没有依赖,应使用 GlobalTaskDispatcher 来实现。
SpecTaskDispatcher 专有任务分发器,绑定到专有线程上的任务分发器。目前已有的专有线程为 UI 线程,通过 UITaskDispatcher 进行任务分发。UITaskDispatcher:绑定到应用主线程的专有任务分发器, 由 Ability 执行 getUITaskDispatcher()创建并返回。 由该分发器分发的所有的任务都是在主线程上按顺序执行,它在应用程序结束时被销毁。
开发使用
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
globalTaskDispatcher.syncDispatch(() -> HiLog.info(LABEL_LOG,"Sync task1 run" + System.lineSeparator()));
HiLog.info(LABEL_LOG,"After sync task1" + System.lineSeparator());
globalTaskDispatcher.syncDispatch(() -> HiLog.info(LABEL_LOG,"Sync task2 run" + System.lineSeparator()));
HiLog.info(LABEL_LOG,"After sync task2" + System.lineSeparator());
复制代码
执行结果:
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
globalTaskDispatcher.asyncDispatch(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
HiLog.error(LABEL_LOG, "%{public}s", "AsyncDispatch InterruptedException");
}
HiLog.info(LABEL_LOG,"Async task1 run" + System.lineSeparator());
});
HiLog.info(LABEL_LOG,"After async task1" + System.lineSeparator());
globalTaskDispatcher.asyncDispatch(() -> {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
HiLog.error(LABEL_LOG, "%{public}s", "AsyncDispatch InterruptedException");
}
HiLog.info(LABEL_LOG,"Async task2 run" + System.lineSeparator());
});
HiLog.info(LABEL_LOG,"After async task2" + System.lineSeparator());
复制代码
执行结果:在两个异步执行中添加延时,更加体现效果
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
final long callTime = System.currentTimeMillis();
globalTaskDispatcher.delayDispatch(() -> {
HiLog.info(LABEL_LOG,"DelayDispatch task1 run" + System.lineSeparator());
final long actualDelayMs = System.currentTimeMillis() - callTime;
HiLog.info(LABEL_LOG,"ActualDelayTime >= delayTime : " + (actualDelayMs >= DELAY_TIME));
}, DELAY_TIME);
HiLog.info(LABEL_LOG,"After delayDispatch task1" + System.lineSeparator());
复制代码
执行结果:
TaskDispatcher dispatcher = createParallelTaskDispatcher("", TaskPriority.DEFAULT);
Group group = dispatcher.createDispatchGroup();
dispatcher.asyncGroupDispatch(group, () -> {
HiLog.info(LABEL_LOG,"GroupTask1 is running" + System.lineSeparator());
});
dispatcher.asyncGroupDispatch(group, () -> {
HiLog.info(LABEL_LOG,"GroupTask2 is running" + System.lineSeparator());
});
dispatcher.groupDispatchNotify(group, () -> HiLog.info(LABEL_LOG,
"此任务在组中的所有任务完成后运行" + System.lineSeparator()));
复制代码
运行结果:结果性不确定、没有执行顺序可言
TaskDispatcher dispatcher = getUITaskDispatcher();
Revocable revocable = dispatcher.delayDispatch(() -> {
HiLog.info(LABEL_LOG,"Delay dispatch" + System.lineSeparator());
}, 50);
boolean revoked = revocable.revoke();
HiLog.info(LABEL_LOG,"Revoke result :" + revoked);
复制代码
运行结果:
TaskDispatcher dispatcher = createParallelTaskDispatcher("SyncBarrierDispatcher", TaskPriority.DEFAULT);
Group group = dispatcher.createDispatchGroup();
dispatcher.asyncGroupDispatch(group, () -> {
HiLog.info(LABEL_LOG,"Task1 is running" + System.lineSeparator());
});
dispatcher.asyncGroupDispatch(group, () -> {
HiLog.info(LABEL_LOG,"Task2 is running" + System.lineSeparator());
});
dispatcher.syncDispatchBarrier(() -> {
HiLog.info(LABEL_LOG,"Barrier" + System.lineSeparator());
});
HiLog.info(LABEL_LOG,"After syncDispatchBarrier" + System.lineSeparator());
复制代码
执行结果:
执行 20 次后结果:
TaskDispatcher dispatcher = createParallelTaskDispatcher("AsyncBarrierDispatcher", TaskPriority.DEFAULT);
Group group = dispatcher.createDispatchGroup();
dispatcher.asyncGroupDispatch(group, () -> {
HiLog.info(LABEL_LOG,"Task1 is running" + System.lineSeparator());
});
dispatcher.asyncGroupDispatch(group, () -> {
HiLog.info(LABEL_LOG,"Task2 is running" + System.lineSeparator());
});
dispatcher.asyncDispatchBarrier(() -> {
HiLog.info(LABEL_LOG,"Barrier" + System.lineSeparator());
});
HiLog.info(LABEL_LOG,"After asyncDispatchBarrier" + System.lineSeparator());
复制代码
执行结果:1 和 2 的执行顺序不定,但总在 3 之前执行;4 不需要等待 1、2、3 执行完成。
final CountDownLatch latch = new CountDownLatch(10);
final ArrayList<Long> indexList = new ArrayList<>(10);
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
//执行10次
globalTaskDispatcher.applyDispatch(index -> {
indexList.add(index);
latch.countDown();
}, 10);
//超时出错
try {
latch.await();
} catch (InterruptedException exception) {
HiLog.error(LABEL_LOG, "%{public}s", "applyDispatchTask InterruptedException");
}
HiLog.info(LABEL_LOG,"List size matches :" + (indexList.size() == TASK_TOTAL));
复制代码
执行结果:
评论