HarmonyOS 基础之线程管理 原创 精华
概述
不同应用在各自独立的进程中运行。当应用以任何形式启动时,系统为其创建进程,该进程将持续运行。当进程完成当前任务处于等待状态,且系统资源不足时,系统自动回收。
在启动应用时,系统会为该应用创建一个称为“主线程”的执行线程。该线程随着应用创建或消失,是应用的核心线程。UI界面的显示和更新等操作,都是在主线程上进行。主线程又称UI线程,默认情况下,所有的操作都是在主线程上执行。如果需要执行比较耗时的任务(如下载文件、查询数据库),可创建其他线程来处理。
如果应用的业务逻辑比较复杂,可能需要创建多个线程来执行多个任务。这种情况下,代码复杂难以维护,任务与线程的交互也会更加繁杂。要解决此问题,开发者可以使用TaskDispatcher来分发不同的任务。
TaskDispatcher介绍
TaskDispatcher是一个任务分发器,它是Ability分发任务的基本接口,隐藏任务所在线程的实现细节。
为保证应用有更好的响应性,我们需要设计任务的优先级。在UI线程上运行的任务默认以高优先级运行,如果某个任务无需等待结果,则可以用低优先级。
线程优先级介绍:
HIGH:最高任务优先级,比默认优先级、低优先级的任务有更高的几率得到执行。
DEFAULT:默认任务优先级, 比低优先级的任务有更高的几率得到执行。
LOW:低任务优先级,比高优先级、默认优先级的任务有更低的几率得到执行。
TaskDispatcher具有多种实现,每种实现对应不同的任务分发器。在分发任务时可以指定任务的优先级,由同一个任务分发器分发出的任务具有相同的优先级。系统提供的任务分发器有GlobalTaskDispatcher、ParallelTaskDispatcher、SerialTaskDispatcher 、SpecTaskDispatcher。
实践
1.同步派发任务syncDispatch
发任务并在当前线程等待任务执行完成。在返回前,当前线程会被阻塞
运行之后查看日志:
从运行结果我们可以看到,只有在当前线程等待任务执行完成之后才会继续往下执行,否则当前线程会被阻塞,所以在使用syncDispatch的时候我们需要注意,如果对syncDispatch使用不当, 将会导致死锁。如下情形可能导致死锁发生:
- 在专有线程上,利用该专有任务分发器进行syncDispatch。
- 在被某个串行任务分发器(dispatcher_a)派发的任务中,再次利用同一个串行任务分发器(dispatcher_a)对象派发任务。
- 在被某个串行任务分发器(dispatcher_a)派发的任务中,经过数次派发任务,最终又利用该(dispatcher_a)串行任务分发器派发任务。例如:dispatcher_a派发的任务使用dispatcher_b进行任务的派发,在dispatcher_b派发的任务中又利用dispatcher_a进行派发任务。
- 串行任务分发器(dispatcher_a)派发的任务中利用串行任务分发器(dispatcher_b)进行同步派发任务,同时dispatcher_b派发的任务中利用串行任务分发器(dispatcher_a)进行同步派发任务。在特定的线程执行顺序下将导致死锁。
2.异步派发任务asyncDispatch
派发任务,并立即返回,返回值是一个可用于取消任务的接口。
运行之后查看日志:
从运行结果我们可以看到,只有在当前线程等待任务执行完成之后才会继续往下执行,否则当前线程会被阻塞,所以在使用
3. 异步延迟派发任务delayDispatch
异步执行,函数立即返回,内部会在延时指定时间后将任务派发到相应队列中。延时时间参数仅代表在这段时间以后任务分发器会将任务加入到队列中,任务的实际执行时间可能晚于这个时间。具体比这个数值晚多久,取决于队列及内部线程池的繁忙情况。
运行之后查看日志:
从运行结果我们可以看出,程序首先执行"after delayDispatch task1",然后执行"delayDispatch task1 run",最后执行"actualDelayTime >= delayTime: %{public}b", (actualDelay >= delayTime),这里 actualDelayTime >= delayTime: true可以看出延时时间参数仅代表在这段时间以后任务分发器会将任务加入到队列中,任务的实际执行时间可能晚于这个时间。
4. 任务组Group
表示一组任务,且该组任务之间有一定的联系,由TaskDispatcher执行createDispatchGroup创建并返回。将任务加入任务组,返回一个用于取消任务的接口。
运行之后查看日志:
5. 同步设置屏障任务syncDispatchBarrier
在任务组上设立任务执行屏障,同步等待任务组中的所有任务执行完成,再执行指定任务。
运行之后查看日志:
6. 异步设置屏障任务asyncDispatchBarrier
在任务组上设立任务执行屏障后直接返回,指定任务将在任务组中的所有任务执行完成后再执行。
运行之后查看日志:
总结
线程它就像一面双刃剑,用的好的时候可以给我们带来事半功倍等效果,用的不好时就会给我们带来困扰,并且这个困扰还不是一时半会能解决掉的(因为发现问题的时候,往往是到了需要优化期了,各项业务相互牵扯),故在项目初期就需要严格考虑考量这些问题了。
作者:汪刚
更多原创内容请关注:开鸿 HarmonyOS 学院
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
哇,很实用的知识
学到了线程优先级的概念了
感谢分享
哈哈哈,基础知识