不同應(yīng)用在各自獨(dú)立的進(jìn)程中運(yùn)行。當(dāng)應(yīng)用以任何形式啟動(dòng)時(shí),系統(tǒng)為其創(chuàng)建進(jìn)程,該進(jìn)程將持續(xù)運(yùn)行。當(dāng)進(jìn)程完成當(dāng)前任務(wù)處于等待狀態(tài),且系統(tǒng)資源不足時(shí),系統(tǒng)自動(dòng)回收。
在啟動(dòng)應(yīng)用時(shí),系統(tǒng)會(huì)為該應(yīng)用創(chuàng)建一個(gè)稱為“主線程”的執(zhí)行線程。該線程隨著應(yīng)用創(chuàng)建或消失,是應(yīng)用的核心線程。UI 界面的顯示和更新等操作,都是在主線程上進(jìn)行。
主線程又稱 UI 線程,默認(rèn)情況下,所有的操作都是在主線程上執(zhí)行。如果需要執(zhí)行比較耗時(shí)的任務(wù)(如下載文件、查詢數(shù)據(jù)庫(kù)),可創(chuàng)建其他線程來處理。
如果應(yīng)用的業(yè)務(wù)邏輯比較復(fù)雜,可能需要?jiǎng)?chuàng)建多個(gè)線程來執(zhí)行多個(gè)任務(wù)。這種情況下,代碼復(fù)雜難以維護(hù),任務(wù)與線程的交互也會(huì)更加繁雜。
要解決此問題,開發(fā)者可以使用 TaskDispatcher 來分發(fā)不同的任務(wù)。
TaskDispatcher 介紹
TaskDispatcher 是一個(gè)任務(wù)分發(fā)器,它是 Ability 分發(fā)任務(wù)的基本接口,隱藏任務(wù)所在線程的實(shí)現(xiàn)細(xì)節(jié)。
為保證應(yīng)用有更好的響應(yīng)性,我們需要設(shè)計(jì)任務(wù)的優(yōu)先級(jí)。在 UI 線程上運(yùn)行的任務(wù)默認(rèn)以高優(yōu)先級(jí)運(yùn)行,如果某個(gè)任務(wù)無需等待結(jié)果,則可以用低優(yōu)先級(jí)。
線程優(yōu)先級(jí)介紹:
HIGH:最高任務(wù)優(yōu)先級(jí),比默認(rèn)優(yōu)先級(jí)、低優(yōu)先級(jí)的任務(wù)有更高的幾率得到執(zhí)行。
DEFAULT:默認(rèn)任務(wù)優(yōu)先級(jí), 比低優(yōu)先級(jí)的任務(wù)有更高的幾率得到執(zhí)行。
LOW:低任務(wù)優(yōu)先級(jí),比高優(yōu)先級(jí)、默認(rèn)優(yōu)先級(jí)的任務(wù)有更低的幾率得到執(zhí)行。
TaskDispatcher 具有多種實(shí)現(xiàn),每種實(shí)現(xiàn)對(duì)應(yīng)不同的任務(wù)分發(fā)器。在分發(fā)任務(wù)時(shí)可以指定任務(wù)的優(yōu)先級(jí),由同一個(gè)任務(wù)分發(fā)器分發(fā)出的任務(wù)具有相同的優(yōu)先級(jí)。
系統(tǒng)提供的任務(wù)分發(fā)器有:
GlobalTaskDispatcher
ParallelTaskDispatcher
SerialTaskDispatcher
SpecTaskDispatcher
實(shí)踐
①同步派發(fā)任務(wù) syncDispatch
發(fā)任務(wù)并在當(dāng)前線程等待任務(wù)執(zhí)行完成。在返回前,當(dāng)前線程會(huì)被阻塞:
/**
* 同步派發(fā)任務(wù)
*/
private void syncDispatch() {
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
globalTaskDispatcher.syncDispatch(new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “sync task1 run”);
}
});
HiLog.info(LABEL_LOG, “after sync task1”);
globalTaskDispatcher.syncDispatch(new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “sync task2 run”);
}
});
HiLog.info(LABEL_LOG, “after sync task2”);
globalTaskDispatcher.syncDispatch(new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “sync task3 run”);
}
});
HiLog.info(LABEL_LOG, “after sync task3”);
}
運(yùn)行之后查看日志:
從運(yùn)行結(jié)果我們可以看到,只有在當(dāng)前線程等待任務(wù)執(zhí)行完成之后才會(huì)繼續(xù)往下執(zhí)行,否則當(dāng)前線程會(huì)被阻塞。
所以在使用 syncDispatch 的時(shí)候我們需要注意,如果對(duì) syncDispatch 使用不當(dāng), 將會(huì)導(dǎo)致死鎖。
如下情形可能導(dǎo)致死鎖發(fā)生:
在專有線程上,利用該專有任務(wù)分發(fā)器進(jìn)行 syncDispatch。
在被某個(gè)串行任務(wù)分發(fā)器(dispatcher_a)派發(fā)的任務(wù)中,再次利用同一個(gè)串行任務(wù)分發(fā)器(dispatcher_a)對(duì)象派發(fā)任務(wù)。
在被某個(gè)串行任務(wù)分發(fā)器(dispatcher_a)派發(fā)的任務(wù)中,經(jīng)過數(shù)次派發(fā)任務(wù),最終又利用該(dispatcher_a)串行任務(wù)分發(fā)器派發(fā)任務(wù)。
例如:dispatcher_a 派發(fā)的任務(wù)使用 dispatcher_b 進(jìn)行任務(wù)的派發(fā),在 dispatcher_b 派發(fā)的任務(wù)中又利用 dispatcher_a 進(jìn)行派發(fā)任務(wù)。
串行任務(wù)分發(fā)器(dispatcher_a)派發(fā)的任務(wù)中利用串行任務(wù)分發(fā)器(dispatcher_b)進(jìn)行同步派發(fā)任務(wù),同時(shí) dispatcher_b 派發(fā)的任務(wù)中利用串行任務(wù)分發(fā)器(dispatcher_a)進(jìn)行同步派發(fā)任務(wù)。在特定的線程執(zhí)行順序下將導(dǎo)致死鎖。
②異步派發(fā)任務(wù) asyncDispatch
派發(fā)任務(wù),并立即返回,返回值是一個(gè)可用于取消任務(wù)的接口。
/**
* 異步派發(fā)任務(wù)
*/
private void asyncDispatch() {
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
Revocable revocable = globalTaskDispatcher.asyncDispatch(new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “async task1 run”);
}
});
HiLog.info(LABEL_LOG, “after async task1”);
}
運(yùn)行之后查看日志:
從運(yùn)行結(jié)果我們可以看到,只有在當(dāng)前線程等待任務(wù)執(zhí)行完成之后才會(huì)繼續(xù)往下執(zhí)行,否則當(dāng)前線程會(huì)被阻塞,所以在使用。
③異步延遲派發(fā)任務(wù) delayDispatch
異步執(zhí)行,函數(shù)立即返回,內(nèi)部會(huì)在延時(shí)指定時(shí)間后將任務(wù)派發(fā)到相應(yīng)隊(duì)列中。
延時(shí)時(shí)間參數(shù)僅代表在這段時(shí)間以后任務(wù)分發(fā)器會(huì)將任務(wù)加入到隊(duì)列中,任務(wù)的實(shí)際執(zhí)行時(shí)間可能晚于這個(gè)時(shí)間。
具體比這個(gè)數(shù)值晚多久,取決于隊(duì)列及內(nèi)部線程池的繁忙情況。
/**
* 異步延遲派發(fā)任務(wù)
*/
private void delayDispatch() {
final long callTime = System.currentTimeMillis();
final long delayTime = 50L;
TaskDispatcher globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
Revocable revocable = globalTaskDispatcher.delayDispatch(new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “delayDispatch task1 run”);
final long actualDelay = System.currentTimeMillis() - callTime;
HiLog.info(LABEL_LOG, “actualDelayTime 》= delayTime: %{public}b”, (actualDelay 》= delayTime));
}
}, delayTime);
HiLog.info(LABEL_LOG, “after delayDispatch task1”);
}
運(yùn)行之后查看日志:
從運(yùn)行結(jié)果我們可以看出:
程序首先執(zhí)行“after delayDispatch task1”
然后執(zhí)行“delayDispatch task1 run”
最后執(zhí)行“actualDelayTime 》= delayTime: %{public}b”, (actualDelay 》= delayTime)
這里 actualDelayTime 》= delayTime: true 可以看出延時(shí)時(shí)間參數(shù)僅代表在這段時(shí)間以后任務(wù)分發(fā)器會(huì)將任務(wù)加入到隊(duì)列中,任務(wù)的實(shí)際執(zhí)行時(shí)間可能晚于這個(gè)時(shí)間。
④任務(wù)組 Group
表示一組任務(wù),且該組任務(wù)之間有一定的聯(lián)系,由 TaskDispatcher 執(zhí)行 createDispatchGroup 創(chuàng)建并返回。
將任務(wù)加入任務(wù)組,返回一個(gè)用于取消任務(wù)的接口。
/**
* 任務(wù)組
*/
private void dispatchGroup() {
String dispatcherName = “parallelTaskDispatcher”;
TaskDispatcher dispatcher = createParallelTaskDispatcher(dispatcherName, TaskPriority.DEFAULT);
// 創(chuàng)建任務(wù)組。
Group group = dispatcher.createDispatchGroup();
// 將任務(wù)1加入任務(wù)組,返回一個(gè)用于取消任務(wù)的接口。
dispatcher.asyncGroupDispatch(group, new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “download task1 is running”);
}
});
// 將與任務(wù)1相關(guān)聯(lián)的任務(wù)2加入任務(wù)組。
dispatcher.asyncGroupDispatch(group, new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “download task2 is running”);
}
});
// 在任務(wù)組中的所有任務(wù)執(zhí)行完成后執(zhí)行指定任務(wù)。
dispatcher.groupDispatchNotify(group, new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “the close task is running after all tasks in the group are completed”);
}
});
}
運(yùn)行之后查看日志:
⑤同步設(shè)置屏障任務(wù) syncDispatchBarrier
在任務(wù)組上設(shè)立任務(wù)執(zhí)行屏障,同步等待任務(wù)組中的所有任務(wù)執(zhí)行完成,再執(zhí)行指定任務(wù)。
/**
* 同步設(shè)置屏障任務(wù)
*/
private void syncDispatchBarrier() {
String dispatcherName = “parallelTaskDispatcher”;
TaskDispatcher dispatcher = createParallelTaskDispatcher(dispatcherName, TaskPriority.DEFAULT);
// 創(chuàng)建任務(wù)組。
Group group = dispatcher.createDispatchGroup();
// 將任務(wù)加入任務(wù)組,返回一個(gè)用于取消任務(wù)的接口。
dispatcher.asyncGroupDispatch(group, new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “task1 is running”); // 1
}
});
dispatcher.asyncGroupDispatch(group, new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “task2 is running”); // 2
}
});
dispatcher.syncDispatchBarrier(new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “barrier”); // 3
}
});
HiLog.info(LABEL_LOG, “after syncDispatchBarrier”); // 4
}
運(yùn)行之后查看日志:
⑥異步設(shè)置屏障任務(wù) asyncDispatchBarrier
在任務(wù)組上設(shè)立任務(wù)執(zhí)行屏障后直接返回,指定任務(wù)將在任務(wù)組中的所有任務(wù)執(zhí)行完成后再執(zhí)行。
/**
* 異步設(shè)置屏障任務(wù)
*/
private void asyncDispatchBarrier() {
TaskDispatcher dispatcher = createParallelTaskDispatcher(“dispatcherName”, TaskPriority.DEFAULT);
// 創(chuàng)建任務(wù)組。
Group group = dispatcher.createDispatchGroup();
// 將任務(wù)加入任務(wù)組,返回一個(gè)用于取消任務(wù)的接口。
dispatcher.asyncGroupDispatch(group, new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “task1 is running”); // 1
}
});
dispatcher.asyncGroupDispatch(group, new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “task2 is running”); // 2
}
});
dispatcher.asyncDispatchBarrier(new Runnable() {
@Override
public void run() {
HiLog.info(LABEL_LOG, “barrier”); // 3
}
});
HiLog.info(LABEL_LOG, “after asyncDispatchBarrier”); // 4
}
運(yùn)行之后查看日志:
總結(jié)
線程它就像一面雙刃劍,用的好的時(shí)候可以給我們帶來事半功倍等效果,用的不好時(shí)就會(huì)給我們帶來困擾。
并且這個(gè)困擾還不是一時(shí)半會(huì)能解決掉的(因?yàn)榘l(fā)現(xiàn)問題的時(shí)候,往往是到了需要優(yōu)化期了,各項(xiàng)業(yè)務(wù)相互牽扯),故在項(xiàng)目初期就需要嚴(yán)格考慮考量這些問題了。
責(zé)任編輯:haq
-
線程
+關(guān)注
關(guān)注
0文章
505瀏覽量
19698 -
鴻蒙系統(tǒng)
+關(guān)注
關(guān)注
183文章
2635瀏覽量
66383
原文標(biāo)題:鴻蒙的線程管理,看完渾身通透!
文章出處:【微信號(hào):gh_834c4b3d87fe,微信公眾號(hào):OpenHarmony技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論