文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

HarmonyOS Sample 之 TaskDispatcher线程管理

2024-12-02 21:57

关注

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

1.介绍

不同应用在各自独立的进程中运行。当应用以任何形式启动时,系统为其创建进程,该进程将持续运行。当进程完成当前任务处于等待状态,且系统资源不足时,系统自动回收。

在启动应用时,系统会为该应用创建一个称为“主线程”的执行线程。该线程随着应用创建或消失,是应用的核心线程。UI界面的显示和更新等操作,都是在主线程上进行。主线程又称UI线程,默认情况下,所有的操作都是在主线程上执行。如果需要执行比较耗时的任务(如下载文件、查询数据库),可创建其他线程来处理。

如果应用的业务逻辑比较复杂,可能需要创建多个线程来执行多个任务。这种情况下,代码复杂难以维护,任务与线程的交互也会更加繁杂。

要解决此问题,开发者可以使用“TaskDispatcher”来分发不同的任务。

比如前段时间 “疫情助手” 的卡片应用,需要获取位置信息并进行逆地理编码,安康码的生成,这些功能就需要单独创建多个线程来执行任务。

2.搭建环境

安装DevEco Studio,详情请参考DevEco Studio下载

设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:

如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。

如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境

下载源码后,使用DevEco Studio 打开项目。

3.理论支持

TaskDispatcher是一个任务分发器,它是Ability分发任务的基本接口,隐藏任务所在线程的实现细节。

TaskDispatcher具有多种实现,每种实现对应不同的任务分发器。在分发任务时可以指定任务的优先级,由同一个任务分发器分发出的任务具有相同的优先级。

系统提供的任务分发器有GlobalTaskDispatcher、ParallelTaskDispatcher、SerialTaskDispatcher 、SpecTaskDispatcher。

线程优先级有HIGH、DEFAULT、LOW,执行几率递减。

分发器提供了常用的操作,

包括:同步派发任务、异步派发任务、异步延迟派发任务、同步设置屏障任务、异步设置屏障任务、执行多次任务、取消任务、任务组等操作。

后面的实例分析中我们会逐个讲解几种任务分发器的概念和用法。

4.实例讲解

4.1.UI界面

UI界面很简单了, 就是为了试验不同类型的任务分发器而设计的按钮,如下图:


4.2.后台代码

重点在这了,官方代码结合API提示,增加了注释说明

4.2.1 GlobalTaskDispatcher 全局并发任务分发器

全局并发任务分发器,由Ability执行getGlobalTaskDispatcher()获取。

适用于任务之间没有联系的情况。一个应用只有一个GlobalTaskDispatcher,它在程序结束时才被销毁。我们从名字也能看出是get而不是createXXX,具有全局唯一性。

a.同步派发任务

  1.  
  2. private void syncTask(Component component) { 
  3.     // 
  4.     StringBuffer stringBuffer = new StringBuffer(); 
  5.     //全局并发任务分发器 
  6.     TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT); 
  7.     HiLog.debug(LABEL_LOG, "task run..."); 
  8.     try { 
  9.         //同步任务1,分派一个任务并等待该任务在当前线程中完成。 
  10.         globalTaskDispatcher.syncDispatch( 
  11.                 () -> { 
  12.                     for (int i = 0; i < 2; i++) { 
  13.                         stringBuffer.append("Sync task1 run").append(System.lineSeparator()); 
  14.                         try { 
  15.                             Thread.sleep(1000); 
  16.                         } catch (InterruptedException e) { 
  17.                             e.printStackTrace(); 
  18.                         } 
  19.                     } 
  20.                     HiLog.debug(LABEL_LOG, "task1 run finished"); 
  21.                 }); 
  22.  
  23.         stringBuffer.append("After sync task1").append(System.lineSeparator()); 
  24.  
  25.         //同步任务2,分派一个任务并等待该任务在当前线程中完成。 
  26.         globalTaskDispatcher.syncDispatch(() -> 
  27.         { 
  28.             for (int i = 0; i < 2; i++) { 
  29.                 stringBuffer.append("Sync task2 run").append(System.lineSeparator()); 
  30.                 try { 
  31.                     Thread.sleep(1000); 
  32.                 } catch (InterruptedException e) { 
  33.                     e.printStackTrace(); 
  34.                 } 
  35.             } 
  36.             HiLog.debug(LABEL_LOG, "task2 run finished"); 
  37.         }); 
  38.  
  39.     } catch (Exception e) { 
  40.         e.printStackTrace(); 
  41.     } 
  42.     stringBuffer.append("After sync task2").append(System.lineSeparator()); 
  43.     HiLog.debug(LABEL_LOG, "task run finished"); 
  44.     resultText.setText(stringBuffer.toString()); 

 输出结果

  1. 09-08 00:13:04.204 5526-5526/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... 
  2. 09-08 00:13:06.206 5526-10427/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Sync task1 run finished 
  3. 09-08 00:13:08.208 5526-10610/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Sync task2 run finished 
  4. 09-08 00:13:08.209 5526-5526/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run finished 

 b.异步派发任务

  1.  
  2. private void asyncTask(Component component) { 
  3.     StringBuffer stringBuffer = new StringBuffer(); 
  4.     HiLog.debug(LABEL_LOG, "Main task run..."); 
  5.  
  6.     //全局并发任务分发器 
  7.     TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT); 
  8.  
  9.     //异步任务,分派任务并立即返回值,无需等待任务执行 
  10.     globalTaskDispatcher.asyncDispatch(() -> { 
  11.         try { 
  12.             Thread.sleep(200); 
  13.         } catch (InterruptedException e) { 
  14.             HiLog.error(LABEL_LOG, "%{public}s""AsyncDispatch InterruptedException"); 
  15.         } 
  16.         stringBuffer.append("Async task1 run").append(System.lineSeparator()); 
  17.  
  18.         //将同步 Runnable 任务发送到事件队列。 该线程被阻塞,直到任务被执行。 
  19.         handler.postSyncTask(() -> resultText.setText(stringBuffer.toString())); 
  20.         HiLog.debug(LABEL_LOG, "Async task1 run finished"); 
  21.     }); 
  22.  
  23.  
  24.     stringBuffer.append("After async task1").append(System.lineSeparator()); 
  25.     HiLog.debug(LABEL_LOG, "Main task run continue"); 
  26.     //异步任务2,分派任务并立即返回值,无需等待任务执行 
  27.     globalTaskDispatcher.asyncDispatch(() -> { 
  28.         try { 
  29.             Thread.sleep(200); 
  30.         } catch (InterruptedException e) { 
  31.             HiLog.error(LABEL_LOG, "%{public}s""AsyncDispatch InterruptedException"); 
  32.         } 
  33.         stringBuffer.append("Async task2 run").append(System.lineSeparator()); 
  34.  
  35.         //将同步 Runnable 任务发送到事件队列。 该线程被阻塞,直到任务被执行。 
  36.         handler.postSyncTask(() -> resultText.setText(stringBuffer.toString())); 
  37.         HiLog.debug(LABEL_LOG, "Async task2 run finished"); 
  38.     }); 
  39.  
  40.     stringBuffer.append("After async task2").append(System.lineSeparator()); 
  41.     HiLog.debug(LABEL_LOG, "Main task run finished"); 
  42.     resultText.setText(stringBuffer.toString()); 

 输出结果

  1. 09-08 00:18:27.779 9609-9609/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... 
  2. 09-08 00:18:27.780 9609-9609/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run continue 
  3. 09-08 00:18:27.781 9609-9609/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run finished 
  4. 09-08 00:18:28.115 9609-613/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task1 run finished 
  5. 09-08 00:18:28.115 9609-614/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task2 run finished 
  6. 或 
  7. 09-08 00:18:58.635 9609-9609/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... 
  8. 09-08 00:18:58.635 9609-9609/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run continue 
  9. 09-08 00:18:58.636 9609-9609/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run finished 
  10. 09-08 00:18:58.840 9609-3584/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task2 run finished 
  11. 09-08 00:18:58.840 9609-3583/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task1 run finished 

 c.异步延迟派发任务

  1.  
  2. private void delayTask(Component component) { 
  3.     StringBuffer stringBuffer = new StringBuffer(); 
  4.  
  5.     //全局并发任务分发器 
  6.     TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT); 
  7.     //调用时间 
  8.     final long callTime = System.currentTimeMillis(); 
  9.     HiLog.debug(LABEL_LOG, "Main task run... current1 time:" + callTime); 
  10.     //延迟任务1,在给定的延迟后分派任务,这是一个异步执行并立即返回一个值而无需等待 
  11.     globalTaskDispatcher.delayDispatch(() -> { 
  12.         stringBuffer.append("DelayDispatch task1 run").append(System.lineSeparator()); 
  13.  
  14.         final long actualDelayMs = System.currentTimeMillis() - callTime; 
  15.  
  16.         stringBuffer.append("ActualDelayTime >= delayTime : ").append((actualDelayMs >= DELAY_TIME)); 
  17.  
  18.         //将同步 Runnable 任务发送到事件队列。 该线程被阻塞,直到任务被执行。 
  19.         handler.postSyncTask(() -> resultText.setText(stringBuffer.toString())); 
  20.         HiLog.debug(LABEL_LOG, "Async task1 run finished duration:" + actualDelayMs); 
  21.     }, DELAY_TIME); 
  22.  
  23.  
  24.     stringBuffer.append("After delayDispatch task1").append(System.lineSeparator()); 
  25.     final long callTime2 = System.currentTimeMillis(); 
  26.     HiLog.debug(LABEL_LOG, "Main task run finished current2 time:" + callTime2); 
  27.     resultText.setText(stringBuffer.toString()); 

输出结果

  1. 09-08 00:20:50.912 9609-9609/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... current1 time:1631031650912 
  2. 09-08 00:20:50.913 9609-9609/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run finished current2 time:1631031650913 
  3. 09-08 00:20:51.916 9609-11689/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task1 run finished duration:1002 

 d.执行多次任务

执行多次任务:对指定任务执行多次。多次执行的顺序也不是固定的。

  1.  
  2. private void applyDispatchTask(Component component) { 
  3.     StringBuilder stringBuilder = new StringBuilder(); 
  4.  
  5.     //倒计时锁存器 
  6.     final CountDownLatch latch = new CountDownLatch(TASK_TOTAL); 
  7.     final ArrayList indexList = new ArrayList<>(TASK_TOTAL); 
  8.  
  9.     TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT); 
  10.     HiLog.debug(LABEL_LOG, "Main task run..."); 
  11.     //执行任务 TASK_TOTAL 次 
  12.     globalTaskDispatcher.applyDispatch(index -> { 
  13.         // 
  14.         indexList.add(index); 
  15.         HiLog.debug(LABEL_LOG, "Async task" + index+" run finished"); 
  16.         //递减锁存器的计数,如果计数达到零,则释放所有等待的线程。 
  17.         latch.countDown(); 
  18.     }, TASK_TOTAL); 
  19.  
  20.     try { 
  21.         // 设置任务超时。 
  22.         latch.await(); 
  23.     } catch (InterruptedException exception) { 
  24.         HiLog.error(LABEL_LOG, "%{public}s""applyDispatchTask InterruptedException"); 
  25.     } 
  26.     stringBuilder.append("List size matches :").append((indexList.size() == TASK_TOTAL)); 
  27.     HiLog.debug(LABEL_LOG, "Main task run finished"); 
  28.     resultText.setText(stringBuilder.toString()); 

 输出结果

  1. 09-08 00:45:23.796 7836-7836/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... 
  2. 09-08 00:45:23.797 7836-18216/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task0 run finished 
  3. 09-08 00:45:23.799 7836-18219/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task3 run finished 
  4. 09-08 00:45:23.800 7836-18220/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task4 run finished 
  5. 09-08 00:45:23.800 7836-18217/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task1 run finished 
  6. 09-08 00:45:23.801 7836-18218/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task2 run finished 
  7. 09-08 00:45:23.801 7836-18221/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task5 run finished 
  8. 09-08 00:45:23.801 7836-18222/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task6 run finished 
  9. 09-08 00:45:23.802 7836-18223/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task7 run finished 
  10. 09-08 00:45:23.802 7836-18224/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task8 run finished 
  11. 09-08 00:45:23.802 7836-18225/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task9 run finished 
  12. 09-08 00:45:23.803 7836-7836/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run finished 

4.2.2 ParallelTaskDispatcher 并发任务分发器

并发任务分发器,由Ability执行createParallelTaskDispatcher()创建并返回。

与GlobalTaskDispatcher不同的是,ParallelTaskDispatcher不具有全局唯一性,可以创建多个。开发者在创建或销毁dispatcher时,需要持有对应的对象引用。

a.同步设置屏障任务

同步设置屏障任务:在任务组上设立任务执行屏障,同步等待任务组中的所有任务执行完成,再执行指定任务。

在全局并发任务分发器(GlobalTaskDispatcher)上同步设置任务屏障,将不会起到屏障作用。

  1.  
  2. private void syncBarrier(Component component) { 
  3.     StringBuffer stringBuffer = new StringBuffer(); 
  4.     //并发任务分发器,不具有全局唯一性,可以创建多个 
  5.     TaskDispatcher dispatcher = createParallelTaskDispatcher("SyncBarrierDispatcher", TaskPriority.DEFAULT); 
  6.     HiLog.debug(LABEL_LOG, "Main task run..."); 
  7.     //创建任务组 
  8.     Group group = dispatcher.createDispatchGroup(); 
  9.  
  10.     //添加异步任务到组中 
  11.     dispatcher.asyncGroupDispatch(group, () -> 
  12.             { 
  13.                 stringBuffer.append("Task1 is running").append(System.lineSeparator()); 
  14.                 HiLog.debug(LABEL_LOG, "Async task1 run finished"); 
  15.             }); 
  16.     dispatcher.asyncGroupDispatch(group, () -> 
  17.     { 
  18.         stringBuffer.append("Task2 is running").append(System.lineSeparator()); 
  19.         HiLog.debug(LABEL_LOG, "Async task2 run finished"); 
  20.     }); 
  21.  
  22.     //同步设置屏障任务,所有任务执行完成,再执行指定任务 
  23.     dispatcher.syncDispatchBarrier(() -> 
  24.     { 
  25.         stringBuffer.append("Barrier").append(System.lineSeparator()); 
  26.         HiLog.debug(LABEL_LOG, "Sync barrier task run finished"); 
  27.     }); 
  28.  
  29.     stringBuffer.append("After syncDispatchBarrier").append(System.lineSeparator()); 
  30.     HiLog.debug(LABEL_LOG, "Main task run finished"); 
  31.     resultText.setText(stringBuffer.toString()); 

 输出结果

  1. 09-08 00:28:49.975 31645-31645/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... 
  2. 09-08 00:28:49.980 31645-13304/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task1 run finished 
  3. 09-08 00:28:49.981 31645-13305/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task2 run finished 
  4. 09-08 00:28:49.982 31645-13306/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Sync barrier task run finished 
  5. 09-08 00:28:49.983 31645-31645/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run finished 
  6. 或 
  7. 09-08 00:32:24.630 31645-31645/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... 
  8. 09-08 00:32:24.633 31645-27346/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task2 run finished 
  9. 09-08 00:32:24.634 31645-27345/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task1 run finished 
  10. 09-08 00:32:24.636 31645-27347/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Sync barrier task run finished 
  11. 09-08 00:32:24.636 31645-31645/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run finished 

 b.异步设置屏障任务

异步设置屏障任务:在任务组上设立任务执行屏障后直接返回,指定任务将在任务组中的所有任务执行完成后再执行。

在全局并发任务分发器(GlobalTaskDispatcher)上异步设置任务屏障,将不会起到屏障作用。

可以使用并发任务分发器(ParallelTaskDispatcher)分离不同的任务组,达到微观并行、宏观串行的行为。

  1.  
  2. private void asyncBarrier(Component component) { 
  3.     StringBuffer stringBuffer = new StringBuffer(); 
  4.     //异步任务分发器,不具有全局唯一性,可以创建多个 
  5.     TaskDispatcher dispatcher = createParallelTaskDispatcher("AsyncBarrierDispatcher", TaskPriority.DEFAULT); 
  6.     HiLog.debug(LABEL_LOG, "Main task run..."); 
  7.     //创建任务组 
  8.     Group group = dispatcher.createDispatchGroup(); 
  9.     //添加异步任务到组中 
  10.     dispatcher.asyncGroupDispatch(group, () -> { 
  11.         stringBuffer.append("Task1 is running").append(System.lineSeparator()); 
  12.  
  13.         handler.postSyncTask(() -> resultText.setText(stringBuffer.toString())); 
  14.         HiLog.debug(LABEL_LOG, "Async Task1 is run finished"); 
  15.     }); 
  16.     //添加异步任务到组中 
  17.     dispatcher.asyncGroupDispatch(group, () -> { 
  18.         stringBuffer.append("Task2 is running").append(System.lineSeparator()); 
  19.         handler.postSyncTask(() -> resultText.setText(stringBuffer.toString())); 
  20.         HiLog.debug(LABEL_LOG, "Async Task2 is run finished"); 
  21.     }); 
  22.     //异步设置屏障任务 
  23.     dispatcher.asyncDispatchBarrier(() -> { 
  24.         stringBuffer.append("Barrier").append(System.lineSeparator()); 
  25.         // 
  26.         handler.postSyncTask(() -> resultText.setText(stringBuffer.toString())); 
  27.         HiLog.debug(LABEL_LOG, "Async barrier task run finished"); 
  28.  
  29.     }); 
  30.     stringBuffer.append("After asyncDispatchBarrier").append(System.lineSeparator()); 
  31.     HiLog.debug(LABEL_LOG, "Main task run finished"); 
  32.  
  33.     resultText.setText(stringBuffer.toString()); 

输出结果

  1. 09-08 00:35:16.089 11855-11855/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... 
  2. 09-08 00:35:16.092 11855-11855/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run finished 
  3. 09-08 00:35:16.094 11855-8290/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async Task1 is run finished 
  4. 09-08 00:35:16.094 11855-8291/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async Task2 is run finished 
  5. 09-08 00:35:16.103 11855-8292/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async barrier task run finished 
  6. 或 
  7. 09-08 00:36:02.736 11855-11855/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... 
  8. 09-08 00:36:02.739 11855-11855/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run finished 
  9. 09-08 00:36:02.742 11855-11611/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async Task2 is run finished 
  10. 09-08 00:36:02.743 11855-11610/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async Task1 is run finished 
  11. 09-08 00:36:02.744 11855-11613/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async barrier task run finished 

c.任务组

任务组:表示一组任务,且该组任务之间有一定的联系,由TaskDispatcher执行createDispatchGroup创建并返回。

将任务加入任务组,返回一个用于取消任务的接口。

  1.  
  2. private void groupTask(Component component) { 
  3.     StringBuffer stringBuffer = new StringBuffer(); 
  4.  
  5.     //并发任务分发器,不具有全局唯一性,可以创建多个 
  6.     TaskDispatcher dispatcher = createParallelTaskDispatcher("MyParallelTaskDispatcher", TaskPriority.DEFAULT); 
  7.     HiLog.debug(LABEL_LOG, "Main task run..."); 
  8.     //创建一个分发组 
  9.     Group group = dispatcher.createDispatchGroup(); 
  10.  
  11.     //异步,将任务1加入任务组,返回一个用于取消任务的接口 
  12.     dispatcher.asyncGroupDispatch(group, () -> { 
  13.         stringBuffer.append("GroupTask1 is running").append(System.lineSeparator()); 
  14.         // 
  15.         handler.postSyncTask(() -> resultText.setText(stringBuffer.toString())); 
  16.  
  17.         HiLog.debug(LABEL_LOG, "Group async task1 finished"); 
  18.     }); 
  19.  
  20.     //异步,将与任务1相关联的任务2加入任务组。 GroupTask1并不一定比GroupTask2先执行完 
  21.     dispatcher.asyncGroupDispatch(group, () -> { 
  22.         stringBuffer.append("GroupTask2 is running").append(System.lineSeparator()); 
  23.         // 
  24.         handler.postSyncTask(() -> resultText.setText(stringBuffer.toString())); 
  25.         HiLog.debug(LABEL_LOG, "Group async task2 run finished"); 
  26.     }); 
  27.  
  28.     //在任务组中的所有任务执行完成后执行指定任务 
  29.     dispatcher.groupDispatchNotify(group, () -> { 
  30.         stringBuffer.append("This task running after all tasks in the group are completed"
  31.                 .append(System.lineSeparator()); 
  32.         HiLog.debug(LABEL_LOG, "This task running after all tasks in the group are completed"); 
  33.     }); 
  34.  
  35.     //最先执行 
  36.     HiLog.debug(LABEL_LOG, "Main task run finished"); 
  37.     resultText.setText(stringBuffer.toString()); 

输出结果

  1. 09-08 00:56:43.891 15624-15624/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... 
  2. 09-08 00:56:43.893 15624-15624/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run finished 
  3. 09-08 00:56:43.895 15624-32143/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Group async task1 finished 
  4. 09-08 00:56:43.895 15624-32144/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Group async task2 run finished 
  5. 09-08 00:56:43.896 15624-32147/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  This task running after all tasks in the group are completed 

 从日志输出看,说明groupDispatchNotify也是一个异步任务。

4.2.3 SerialTaskDispatcher 串行任务分发器

串行任务分发器,由Ability执行createSerialTaskDispatcher()创建并返回。由该分发器分发的所有的任务都是按顺序执行,但是执行这些任务的线程并不是固定的。

如果要执行并行任务,应使用ParallelTaskDispatcher或者GlobalTaskDispatcher,而不是创建多个SerialTaskDispatcher。

如果任务之间没有依赖,应使用GlobalTaskDispatcher来实现。它的创建和销毁由开发者自己管理,开发者在使用期间需要持有该对象引用。

  1.  
  2. private void serialTaskDispatcherTask(Component component) { 
  3.     StringBuffer stringBuffer = new StringBuffer(); 
  4.     TaskDispatcher serialTaskDispatcher =createSerialTaskDispatcher("MySerialTaskDispatcher",TaskPriority.DEFAULT); 
  5.     HiLog.debug(LABEL_LOG, "Main task run..."); 
  6.  
  7.     
  8.  
  9.  
  10.     //异步任务1,分派一个任务并等待该任务在当前线程中完成。 
  11.     serialTaskDispatcher.asyncDispatch( 
  12.             () -> { 
  13.                 try { 
  14.                     Thread.sleep(3); 
  15.                 } catch (InterruptedException e) { 
  16.                     e.printStackTrace(); 
  17.                 } 
  18.                 stringBuffer.append("Async task1 run").append(System.lineSeparator()); 
  19.                 handler.postSyncTask(() -> resultText.setText(stringBuffer.toString())); 
  20.                 HiLog.debug(LABEL_LOG, "Async task1 run finished"); 
  21.             }); 
  22.  
  23.     stringBuffer.append("After sync task1").append(System.lineSeparator()); 
  24.  
  25.     //异步任务2,分派一个任务并等待该任务在当前线程中完成。 
  26.     serialTaskDispatcher.asyncDispatch(() -> 
  27.     { 
  28.         try { 
  29.             Thread.sleep(3); 
  30.         } catch (InterruptedException e) { 
  31.             e.printStackTrace(); 
  32.         } 
  33.         stringBuffer.append("Async task2 run").append(System.lineSeparator()); 
  34.         handler.postSyncTask(() -> resultText.setText(stringBuffer.toString())); 
  35.         HiLog.debug(LABEL_LOG, "Async task2 run finished"); 
  36.     }); 
  37.     //异步任务3,分派一个任务并等待该任务在当前线程中完成。 
  38.     serialTaskDispatcher.asyncDispatch(() -> 
  39.     { 
  40.         try { 
  41.             Thread.sleep(3); 
  42.         } catch (InterruptedException e) { 
  43.             e.printStackTrace(); 
  44.         } 
  45.         stringBuffer.append("Async task3 run").append(System.lineSeparator()); 
  46.         handler.postSyncTask(() -> resultText.setText(stringBuffer.toString())); 
  47.         HiLog.debug(LABEL_LOG, "Async task3 run finished"); 
  48.     }); 
  49.  
  50.     HiLog.debug(LABEL_LOG, "Main task run finished"); 
  51.     resultText.setText(stringBuffer.toString()); 

输出结果

同步派发任务

  1. 09-08 01:32:17.493 7945-7945/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... 
  2. 09-08 01:32:19.494 7945-2486/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Sync task1 run finished 
  3. 09-08 01:32:21.496 7945-2725/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Sync task2 run finished 
  4. 09-08 01:32:21.497 7945-7945/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run finished 
  5.  
  6. 异步派发任务、 
  7. -08 01:37:07.276 8419-8419/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... 
  8. 09-08 01:37:07.277 8419-8419/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run finished 
  9. 09-08 01:37:07.277 8419-24172/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task1 run finished 
  10. 09-08 01:37:07.288 8419-24173/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task2 run finished 
  11. 09-08 01:37:07.290 8419-24178/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Async task3 run finished 

从输出看出所有的任务都是按顺序执行的。

4.2.4 SpecTaskDispatcher 专有任务分发器

专有任务分发器,绑定到专有线程上的任务分发器。目前已有的专有线程为UI线程,通过UITaskDispatcher进行任务分发。

UITaskDispatcher:绑定到应用主线程的专有任务分发器, 由Ability执行getUITaskDispatcher()创建并返回。 由该分发器分发的所有的任务都是在主线程上按顺序执行,它在应用程序结束时被销毁。

a.取消任务

取消任务:Revocable是取消一个异步任务的接口。

异步任务包括通过 asyncDispatch、delayDispatch、asyncGroupDispatch 派发的任务。如果任务已经在执行中或执行完成,则会返回取消失败。

  1.  
  2. private void postTaskAndRevoke(Component component) { 
  3.     StringBuffer stringBuffer = new StringBuffer(); 
  4.  
  5.     //专有任务分发器,绑定到应用主线程的专有任务分发器 
  6.     TaskDispatcher dispatcher = getUITaskDispatcher(); 
  7.     HiLog.debug(LABEL_LOG, "Main task run..."); 
  8.     //延迟分发器 
  9.     Revocable revocable = dispatcher.delayDispatch(() -> { 
  10.         stringBuffer.append("Delay dispatch").append(System.lineSeparator()); 
  11.         // 
  12.         handler.postSyncTask(() -> resultText.setText(stringBuffer.toString())); 
  13.         HiLog.debug(LABEL_LOG, "Delay task run finished"); 
  14.     }, 5); 
  15.  
  16.     //取消异步任务 
  17.     boolean revoked = revocable.revoke(); 
  18.     stringBuffer.append("Revoke result :").append(revoked); 
  19.     HiLog.debug(LABEL_LOG, "Main task::delay task revocable finished"); 
  20.     resultText.setText(stringBuffer.toString()); 

输出结果

  1. 09-08 01:00:27.184 13669-13669/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task run... 
  2. 09-08 01:00:27.184 13669-13669/ohos.samples.taskmanager D 00F00/=>MainAbilitySlice:  Main task::delay task revocable finished 

取消成功,所以Delay task run finished 日志并没有打印。

完整代码

附件直接下载

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

来源:鸿蒙社区内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯