1、线程管理&任务分发

1、线程管理&任务分发

作者:韩茹

公司:程序咖(北京)科技有限公司

鸿蒙巴士专栏作家

一、线程管理概述

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

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

二、任务分发TaskDispatcher

如果应用的业务逻辑比较复杂,可能需要创建多个线程来执行多个任务。这种情况下,代码复杂难以维护,任务与线程的交互也会更加繁杂。要解决此问题,开发者可以使用“TaskDispatcher”来分发不同的任务。

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

  • TaskDispatcher是一个任务分发器将任务发布到任务调度器的基本接口。

  • TaskDispatcher隐藏了底层线程实现的细节,包括创建、销毁和重用。

  • TaskDispatcher支持在几乎所有场景中执行同步、异步、串行和并行任务。

为保证应用有更好的响应性,我们需要设计任务的优先级。在UI线程上运行的任务默认以高优先级运行,如果某个任务无需等待结果,则可以用低优先级。

优先级详细描述
HIGH最高任务优先级,比默认优先级、低优先级的任务有更高的几率得到执行。
DEFAULT默认任务优先级, 比低优先级的任务有更高的几率得到执行。
LOW低任务优先级,比高优先级、默认优先级的任务有更低的几率得到执行。

TaskDispatcher具有多种实现,每种实现对应不同的任务分发器。在分发任务时可以指定任务的优先级,由同一个任务分发器分发出的任务具有相同的优先级。系统提供的任务分发器有GlobalTaskDispatcher、ParallelTaskDispatcher、SerialTaskDispatcher 、SpecTaskDispatcher。

  • GlobalTaskDispatcher

全局并发任务分发器,由Ability执行getGlobalTaskDispatcher()获取。适用于任务之间没有联系的情况。一个应用只有一个GlobalTaskDispatcher,它在程序结束时才被销毁。

TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
  • ParallelTaskDispatcher

并发任务分发器,由Ability执行createParallelTaskDispatcher()创建并返回。与GlobalTaskDispatcher不同的是,ParallelTaskDispatcher不具有全局唯一性,可以创建多个。开发者在创建或销毁dispatcher时,需要持有对应的对象引用 。

String dispatcherName = "parallelTaskDispatcher";
TaskDispatcher parallelTaskDispatcher = createParallelTaskDispatcher(dispatcherName, TaskPriority.DEFAULT);
  • SerialTaskDispatcher

串行任务分发器,由Ability执行createSerialTaskDispatcher()创建并返回。由该分发器分发的所有的任务都是按顺序执行,但是执行这些任务的线程并不是固定的。如果要执行并行任务,应使用ParallelTaskDispatcher或者GlobalTaskDispatcher,而不是创建多个SerialTaskDispatcher。如果任务之间没有依赖,应使用GlobalTaskDispatcher来实现。它的创建和销毁由开发者自己管理,开发者在使用期间需要持有该对象引用。

String dispatcherName = "serialTaskDispatcher";
TaskDispatcher serialTaskDispatcher = createSerialTaskDispatcher(dispatcherName, TaskPriority.DEFAULT);
  • SpecTaskDispatcher

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

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

TaskDispatcher uiTaskDispatcher = getUITaskDispatcher();

该接口中常用方法:

public interface TaskDispatcher {
    void syncDispatch(Runnable var1); //分派任务,并在当前线程中等待直到任务完成。

    Revocable asyncDispatch(Runnable var1); //异步分派任务

    Revocable delayDispatch(Runnable var1, long var2);

    void syncDispatchBarrier(Runnable var1);

    void asyncDispatchBarrier(Runnable var1);

    Group createDispatchGroup();

    Revocable asyncGroupDispatch(Group var1, Runnable var2);

    boolean groupDispatchWait(Group var1, long var2);

    void groupDispatchNotify(Group var1, Runnable var2);

    void applyDispatch(Consumer<Long> var1, long var2);
}

三、开发步骤

3.1 同步分发

syncDispatch

同步派发任务:派发任务并在当前线程等待任务执行完成。在返回前,当前线程会被阻塞。

我们在ability_main.xml文件中添加一个按钮:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="10vp"
    ohos:orientation="vertical">

    <Button
        ohos:id="$+id:btn1"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="同步分发syncDispatch"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        ohos:margin="10vp"
        />

</DirectionalLayout>

然后在MainAbilitySlice中我们来处理按钮的点击事件,通过观察日期,来了解任务分发:

package com.example.hanrutaskdispatcher.slice;

import com.example.hanrutaskdispatcher.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class MainAbilitySlice extends AbilitySlice {
    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");
    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);

        initComponent();
    }

    public void initComponent(){
        findComponentById(ResourceTable.Id_btn1).setClickedListener(component ->syncDispatch() );
    }

    // 1.同步分发
    public void syncDispatch(){
        // 1.获取一个任务分发器,全局的
        TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);

        // 2.同步分发,在当前线程中等待直到任务完成。
        globalTaskDispatcher.syncDispatch(new Runnable() {
            @Override
            public void run() {
                HiLog.info(LABEL,"->同步任务1,在运行ing。。");
            }
        });
        HiLog.info(LABEL,"->同步任务1,后面。。");
        // 也可以简写:Lambda表达式
        globalTaskDispatcher.syncDispatch(() -> {
            HiLog.info(LABEL,"-->同步任务2,在运行ing。。");
        });
        HiLog.info(LABEL,"-->同步任务2,后面。。");

        globalTaskDispatcher.syncDispatch(() -> {
            HiLog.info(LABEL,"--->同步任务3,在运行ing。。");
        });
        HiLog.info(LABEL,"--->同步任务3,后面。。");

    }
}

运行程序, 并点击按钮1:

WX20210629-103814@2x

说明

如果对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)进行同步派发任务。在特定的线程执行顺序下将导致死锁。
3.2 异步分发

asyncDispatch

异步派发任务:派发任务,并立即返回,返回值是一个可用于取消任务的接口。

在ability_main.xml中再添加一个按钮:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="10vp"
    ohos:orientation="vertical">

		...

    <Button
        ohos:id="$+id:btn2"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="异步分发asyncDispatch"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        ohos:margin="10vp"
        />

</DirectionalLayout>

在MainAbilitySlice中处理第二个按钮的异步分发:

		// 2.异步分发
    public void asyncDispatch(){
        // 1.获取一个任务分发器,全局的
        TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);

        // 2.异步分发任务,返回值是一个Revocable,可以用于取消任务
        Revocable revocable=globalTaskDispatcher.asyncDispatch(() -> {
            HiLog.info(LABEL,"->异步任务1,在运行ing。。");
        });
        HiLog.info(LABEL,"->异步任务1,后面。。");

        globalTaskDispatcher.asyncDispatch(() -> {
            HiLog.info(LABEL,"-->异步任务2,在运行ing。。");
        });
        HiLog.info(LABEL,"-->异步任务2,后面。。");

        globalTaskDispatcher.asyncDispatch(() -> {
            HiLog.info(LABEL,"--->异步任务3,在运行ing。。");
        });
        HiLog.info(LABEL,"--->异步任务3,后面。。");
    }
public void initComponent(){
        findComponentById(ResourceTable.Id_btn1).setClickedListener(component ->syncDispatch() );
        findComponentById(ResourceTable.Id_btn2).setClickedListener(component ->asyncDispatch() );
    }

运行结果每次可能都不太一样:

WX20210629-111243@2x

3.3 延迟分发

delayDispatch

异步延迟派发任务:异步执行,函数立即返回,内部会在延时指定时间后将任务派发到相应队列中。延时时间参数仅代表在这段时间以后任务分发器会将任务加入到队列中,任务的实际执行时间可能晚于这个时间。具体比这个数值晚多久,取决于队列及内部线程池的繁忙情况。

在ability_main.xml中再添加一个按钮:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="10vp"
    ohos:orientation="vertical">

    ...

    <Button
        ohos:id="$+id:btn3"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="延迟分发delayDispatch"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        ohos:margin="10vp"
        />

</DirectionalLayout>

在MainAbilitySlice中处理第三个按钮的异步分发:

		public void initComponent(){
        findComponentById(ResourceTable.Id_btn1).setClickedListener(component ->syncDispatch() );
        findComponentById(ResourceTable.Id_btn2).setClickedListener(component ->asyncDispatch() );
        findComponentById(ResourceTable.Id_btn3).setClickedListener(component ->delayDispatch() );
    }

    // 3.延迟分发
    public void delayDispatch(){
        // 获取系统当前的时间
        final long callTime = System.currentTimeMillis();
        // 设置要延迟的时间
        final long delayTime = 50L;
        // 创建一个全局的任务分发器
        TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
        // 延迟分发,返回一个Revocable可以用于取消任务
        Revocable revocable = globalTaskDispatcher.delayDispatch(new Runnable() {
            @Override
            public void run() {
                HiLog.info(LABEL, "->延迟任务1,在运行ing。。");
                final long actualDelay = System.currentTimeMillis() - callTime;//  实际延迟时间
                HiLog.info(LABEL, "actualDelayTime:%{public}d ,delayTime:%{public}d , actualDelayTime >= delayTime: %{public}b",actualDelay,delayTime, (actualDelay >= delayTime));

            }
        }, delayTime);
        HiLog.info(LABEL, "->延迟任务1,之后。。");

    }

运行结果:

WX20210629-113735@2x

3.4 任务组

Group

任务组:表示一组任务,且该组任务之间有一定的联系,由TaskDispatcher执行createDispatchGroup创建并返回。将任务加入任务组,返回一个用于取消任务的接口。

在ability_main.xml中再添加一个按钮:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="10vp"
    ohos:orientation="vertical">

    ...
    <Button
        ohos:id="$+id:btn4"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="任务组Group"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        ohos:margin="10vp"
        />

</DirectionalLayout>

在MainAbilitySlice中处理第四个按钮的异步分发:

 public void initComponent() {
        findComponentById(ResourceTable.Id_btn1).setClickedListener(component -> syncDispatch());
        findComponentById(ResourceTable.Id_btn2).setClickedListener(component -> asyncDispatch());
        findComponentById(ResourceTable.Id_btn3).setClickedListener(component -> delayDispatch());
        findComponentById(ResourceTable.Id_btn4).setClickedListener(component -> testGroup());
    }

    // 4.任务组
    // 将一系列相关联的下载任务放入一个任务组,执行完下载任务后关闭应用。
    public void testGroup() {
        String dispatcherName = "parallelTaskDispatcher"; //并行任务分配器
        TaskDispatcher dispatcher = createParallelTaskDispatcher(dispatcherName, TaskPriority.DEFAULT);
        // 创建任务组:
        Group group = dispatcher.createDispatchGroup();
        // 将任务1加入任务组,返回一个用于取消任务的接口。
        dispatcher.asyncGroupDispatch(group, new Runnable() {
            @Override
            public void run() {
                HiLog.info(LABEL, "--->下载任务1,正在运行。。");
            }
        });
        // 将与任务1相关联的任务2加入任务组。
        dispatcher.asyncGroupDispatch(group, new Runnable() {
            @Override
            public void run() {
                HiLog.info(LABEL, "--->下载任务2,正在运行。。");
            }
        });
        // 在任务组中的所有任务执行完成后执行指定任务。
        dispatcher.groupDispatchNotify(group, new Runnable() {
            @Override
            public void run() {
                HiLog.info(LABEL, "任务组中的所有任务都执行完毕后,执行这个关闭任务 ing。。。");
            }
        });

    }

多执行几次,可能运行结果是不一样的,这里我点击了3次按钮:

WX20210629-114901@2x

3.5 取消任务

Revocable

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

在ability_main.xml中再添加一个按钮:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="10vp"
    ohos:orientation="vertical">

    ...
    
    <Button
        ohos:id="$+id:btn5"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="取消任务Revocable"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        ohos:margin="10vp"
        />

</DirectionalLayout>

在MainAbilitySlice中处理第五个按钮的异步分发:

public void initComponent() {
        findComponentById(ResourceTable.Id_btn1).setClickedListener(component -> syncDispatch());
        findComponentById(ResourceTable.Id_btn2).setClickedListener(component -> asyncDispatch());
        findComponentById(ResourceTable.Id_btn3).setClickedListener(component -> delayDispatch());
        findComponentById(ResourceTable.Id_btn4).setClickedListener(component -> testGroup());
        findComponentById(ResourceTable.Id_btn5).setClickedListener(component -> revocableTask());
    }

    // 5.取消任务
    public void revocableTask(){
        TaskDispatcher dispatcher = getUITaskDispatcher();
        Revocable revocable = dispatcher.delayDispatch(new Runnable() {
            @Override
            public void run() {
                HiLog.info(LABEL, "延迟分发。。");
            }
        }, 10);

        boolean revoked = revocable.revoke(); // 撤销
        HiLog.info(LABEL, "%{public}b", revoked);
    }

执行结果可能是true,也可能是 false:

WX20210629-135823@2x

3.6 同步设置屏障任务

syncDispatchBarrier

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

说明

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

在ability_main.xml中再添加一个按钮:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="10vp"
    ohos:orientation="vertical">

    ...
    <Button
        ohos:id="$+id:btn6"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="同步设置屏障任务syncDispatchBarrier"
        ohos:multiple_lines="true"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        ohos:margin="10vp"
        />

</DirectionalLayout>

在MainAbilitySlice中处理第六个按钮的异步分发:

public void initComponent() {
        findComponentById(ResourceTable.Id_btn1).setClickedListener(component -> syncDispatch());
        findComponentById(ResourceTable.Id_btn2).setClickedListener(component -> asyncDispatch());
        findComponentById(ResourceTable.Id_btn3).setClickedListener(component -> delayDispatch());
        findComponentById(ResourceTable.Id_btn4).setClickedListener(component -> testGroup());
        findComponentById(ResourceTable.Id_btn5).setClickedListener(component -> revocableTask());
        findComponentById(ResourceTable.Id_btn6).setClickedListener(component -> syncDispatchBarrier());
    }

    // 6.同步设置屏障任务
    public void syncDispatchBarrier(){
        String dispatcherName = "parallelTaskDispatcher";
        TaskDispatcher dispatcher = createParallelTaskDispatcher(dispatcherName, TaskPriority.DEFAULT);
        // 创建任务组。
        Group group = dispatcher.createDispatchGroup();
        // 将任务加入任务组,返回一个用于取消任务的接口。
        dispatcher.asyncGroupDispatch(group, new Runnable() {
            @Override
            public void run() {
                HiLog.info(LABEL, "异步任务1,在运行ing。。");  // 1
            }
        });
        dispatcher.asyncGroupDispatch(group, new Runnable() {
            @Override
            public void run() {
                HiLog.info(LABEL, "异步任务2,在运行ing。。");  // 2
            }
        });

        dispatcher.syncDispatchBarrier(new Runnable() {
            @Override
            public void run() {
                HiLog.info(LABEL, "屏障任务");  // 3
            }
        });
        HiLog.info(LABEL, "同步设置屏障任务后。。");  // 4

    }

多执行几次,可能运行结果是不一样的:1和2的执行顺序不定;3和4总是在1和2之后按顺序执行。

WX20210629-141126@2x

3.7 异步设置屏障任务

asyncDispatchBarrier

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

说明

在全局并发任务分发器(GlobalTaskDispatcher)上异步设置任务屏障,将不会起到屏障作用。可以使用并发任务分发器(ParallelTaskDispatcher)分离不同的任务组,达到微观并行、宏观串行的行为。

在ability_main.xml中再添加一个按钮:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:padding="10vp"
    ohos:orientation="vertical">

    ...
    <Button
        ohos:id="$+id:btn7"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:text="异步设置屏障任务asyncDispatchBarrier"
        ohos:multiple_lines="true"
        ohos:text_size="25fp"
        ohos:background_element="#EEEEEE"
        ohos:padding="10vp"
        ohos:margin="10vp"
        />

</DirectionalLayout>

在MainAbilitySlice中处理第七个按钮的异步分发:

public void initComponent() {
        findComponentById(ResourceTable.Id_btn1).setClickedListener(component -> syncDispatch());
        findComponentById(ResourceTable.Id_btn2).setClickedListener(component -> asyncDispatch());
        findComponentById(ResourceTable.Id_btn3).setClickedListener(component -> delayDispatch());
        findComponentById(ResourceTable.Id_btn4).setClickedListener(component -> testGroup());
        findComponentById(ResourceTable.Id_btn5).setClickedListener(component -> revocableTask());
        findComponentById(ResourceTable.Id_btn6).setClickedListener(component -> syncDispatchBarrier());
        findComponentById(ResourceTable.Id_btn7).setClickedListener(component -> asyncDispatchBarrier());
    }

    // 7.异步设置屏障任务
    public void asyncDispatchBarrier(){
        TaskDispatcher dispatcher = createParallelTaskDispatcher("dispatcherName", TaskPriority.DEFAULT);
// 创建任务组。
        Group group = dispatcher.createDispatchGroup();
// 将任务加入任务组,返回一个用于取消任务的接口。
        dispatcher.asyncGroupDispatch(group, new Runnable() {
            @Override
            public void run() {
                HiLog.info(LABEL, "异步任务1,在运行ing。。");  // 1
            }
        });
        dispatcher.asyncGroupDispatch(group, new Runnable() {
            @Override
            public void run() {
                HiLog.info(LABEL, "异步任务2,在运行ing。。");  // 2
            }
        });

        dispatcher.asyncDispatchBarrier(new Runnable() {
            @Override
            public void run() {
                HiLog.info(LABEL, "屏障任务");  // 3
            }
        });
        HiLog.info(LABEL, "异步设置屏障任务后。。");  // 4

        // 1和2的执行顺序不定,但总在3之前执行;4不需要等待1、2、3执行完成。
    }

多执行几次,可能运行结果是不一样的:1和2的执行顺序不定,但总在3之前执行;4不需要等待1、2、3执行完成。

WX20210629-141858@2x

3.8 执行多次任务

applyDispatch

执行多次任务:对指定任务执行多次。

在ability_main.xml中再添加一个按钮,这里按钮太多了,一屏高度已经摆放不下了,所以我们外层嵌套一个ScrollView,滚动起来

<?xml version="1.0" encoding="utf-8"?>


<ScrollView
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_content"
    ohos:width="match_parent"
    >

    <DirectionalLayout
        ohos:height="match_parent"
        ohos:width="match_parent"
        >

        ...

        <Button
            ohos:id="$+id:btn8"
            ohos:height="match_content"
            ohos:width="match_content"
            ohos:background_element="#EEEEEE"
            ohos:margin="10vp"
            ohos:multiple_lines="true"
            ohos:padding="10vp"
            ohos:text="执行多次任务applyDispatch"
            ohos:text_size="25fp"
            />
    </DirectionalLayout>
</ScrollView>

在MainAbilitySlice中处理第七个按钮的异步分发:

public void initComponent() {
        findComponentById(ResourceTable.Id_btn1).setClickedListener(component -> syncDispatch());
        findComponentById(ResourceTable.Id_btn2).setClickedListener(component -> asyncDispatch());
        findComponentById(ResourceTable.Id_btn3).setClickedListener(component -> delayDispatch());
        findComponentById(ResourceTable.Id_btn4).setClickedListener(component -> testGroup());
        findComponentById(ResourceTable.Id_btn5).setClickedListener(component -> revocableTask());
        findComponentById(ResourceTable.Id_btn6).setClickedListener(component -> syncDispatchBarrier());
        findComponentById(ResourceTable.Id_btn7).setClickedListener(component -> asyncDispatchBarrier());
        findComponentById(ResourceTable.Id_btn8).setClickedListener(component -> applyDispatch());
    }
    // 8.执行多次任务:对指定任务执行多次。
    public void applyDispatch(){
        final int total = 10;
        // 一种同步辅助工具,允许一个或多个线程等待一组在其他线程中执行的操作完成。
        final CountDownLatch latch = new CountDownLatch(total);
        final List<Long> indexList = new ArrayList<>(total);
        TaskDispatcher dispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);

        // 执行任务 total 次。
        dispatcher.applyDispatch((index) -> {
            indexList.add(index);
            latch.countDown();
        }, total);
        // 设置任务超时。
        try {
            latch.await();
        } catch (InterruptedException exception) {
            HiLog.error(LABEL, "latch exception");
        }
        HiLog.info(LABEL, "list size matches, %{public}b", (total == indexList.size()));

    }

执行:

WX20210629-143654@2x

更多内容:

1、社区:鸿蒙巴士https://www.harmonybus.net/

2、公众号:HarmonyBus

3、技术交流QQ群:714518656

4、视频课:https://www.chengxuka.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值