與JAVA Executor的區(qū)別
vertx框架提供了OrderedExecutor的實(shí)現(xiàn),其能保證提交的任務(wù)按照嚴(yán)格的提交順序執(zhí)行,在idk Executor的線程池中,多線程情況下可能無法保證提交的任務(wù)順序執(zhí)行。
源碼分析
下面看下vertx的OrderedExecutor實(shí)現(xiàn),其源碼并不長(zhǎng),如下:
private static final class OrderedExecutor implements Executor {
private final LinkedList<Runnable> tasks = new LinkedList<>();
private boolean running;
private final Executor parent;
private final Runnable runner;
public OrderedExecutor(Executor parent) {
this.parent = parent;
runner = () -> {
for (; ; ) {
final Runnable task;
synchronized (tasks) {
task = tasks.poll();
if (task == null) {
running = false;
return;
}
}
try {
task.run();
} catch (Throwable t) {
log.error("Caught unexpected Throwable", t);
}
}
};
}
public void execute(Runnable command) {
synchronized (tasks) {
tasks.add(command);
if (!running) {
running = true;
parent.execute(runner);
}
}
}
}
OrderedExecutor包含4個(gè)成員變量,tasks(LinkedList<Runnable>)是runnable隊(duì)列,parent(Executor)是真正執(zhí)行runnable的執(zhí)行器,runner(Runnable)是順序執(zhí)行器要執(zhí)行的任務(wù),running為運(yùn)行狀態(tài)標(biāo)志。
首先分析runner,其運(yùn)行的任務(wù)是個(gè)循環(huán)任務(wù),只有當(dāng)tasks中沒有要執(zhí)行的任務(wù)了才退出。其邏輯很簡(jiǎn)單,就是循環(huán)從tasks中獲取任務(wù)并執(zhí)行。
再看execute方法,其邏輯也很簡(jiǎn)單,就是向tasks中添加runnable,如果runner沒有執(zhí)行,那么就將其提交給parent線程池運(yùn)行起來。
因?yàn)閞unner是按順序從tasks中取任務(wù)執(zhí)行的,因此保證了該OrderedExecutor execute的任務(wù)是按順序執(zhí)行的。
再介紹下創(chuàng)建OrderedExecutor的工廠類OrderedExecutorFactory,其代碼如下:
public class OrderedExecutorFactory {
static final Logger log = LoggerFactory.getLogger(OrderedExecutorFactory.class);
private final Executor parent;
public OrderedExecutorFactory(Executor parent) {
this.parent = parent;
}
public OrderedExecutor getExecutor() {
return new OrderedExecutor(parent);
}
}
其代碼更簡(jiǎn)單,就是傳入一個(gè)線程池執(zhí)行器parent,每次創(chuàng)建OrderedExecutor要共享這個(gè)parent執(zhí)行器。
下面分析下OrderedExecutor和Executor的關(guān)系,雖然OrderedExecutor實(shí)現(xiàn)了Executor,但它們并不是簡(jiǎn)單的平行對(duì)等關(guān)系,1個(gè)Executor可以對(duì)應(yīng)多個(gè)OrderedExecutor。
1個(gè)Executor相當(dāng)于1個(gè)線程池,但每個(gè)OrderedExecutor在運(yùn)行狀態(tài)會(huì)獨(dú)占1個(gè)線程,因?yàn)樵诎裷unner提交給parent執(zhí)行時(shí),parent會(huì)選出1個(gè)空閑線程執(zhí)行該runner,而該runner是個(gè)循環(huán)任務(wù),會(huì)獨(dú)占這個(gè)線程。
OrderedExecutor通過1個(gè)runner任務(wù)處理所有提交到該OrderedExecutor的runnable,當(dāng)處理完tasks中所有任務(wù)后就把線程歸還給parent(Executor),當(dāng)下次有新的runnable提交進(jìn)來時(shí)再把runner提交給parent(Executor),parent再取出1個(gè)空閑線程運(yùn)行runner,這個(gè)runner又獨(dú)占了這個(gè)線程。