與JAVA Executor的區(qū)別
vertx框架提供了OrderedExecutor的實現(xiàn),其能保證提交的任務(wù)按照嚴(yán)格的提交順序執(zhí)行,在idk Executor的線程池中,多線程情況下可能無法保證提交的任務(wù)順序執(zhí)行。
源碼分析
下面看下vertx的OrderedExecutor實現(xiàn),其源碼并不長,如下:
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個成員變量,tasks(LinkedList<Runnable>)是runnable隊列,parent(Executor)是真正執(zhí)行runnable的執(zhí)行器,runner(Runnable)是順序執(zhí)行器要執(zhí)行的任務(wù),running為運行狀態(tài)標(biāo)志。
首先分析runner,其運行的任務(wù)是個循環(huán)任務(wù),只有當(dāng)tasks中沒有要執(zhí)行的任務(wù)了才退出。其邏輯很簡單,就是循環(huán)從tasks中獲取任務(wù)并執(zhí)行。
再看execute方法,其邏輯也很簡單,就是向tasks中添加runnable,如果runner沒有執(zhí)行,那么就將其提交給parent線程池運行起來。
因為runner是按順序從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);
}
}
其代碼更簡單,就是傳入一個線程池執(zhí)行器parent,每次創(chuàng)建OrderedExecutor要共享這個parent執(zhí)行器。
下面分析下OrderedExecutor和Executor的關(guān)系,雖然OrderedExecutor實現(xiàn)了Executor,但它們并不是簡單的平行對等關(guān)系,1個Executor可以對應(yīng)多個OrderedExecutor。
1個Executor相當(dāng)于1個線程池,但每個OrderedExecutor在運行狀態(tài)會獨占1個線程,因為在把runner提交給parent執(zhí)行時,parent會選出1個空閑線程執(zhí)行該runner,而該runner是個循環(huán)任務(wù),會獨占這個線程。
OrderedExecutor通過1個runner任務(wù)處理所有提交到該OrderedExecutor的runnable,當(dāng)處理完tasks中所有任務(wù)后就把線程歸還給parent(Executor),當(dāng)下次有新的runnable提交進來時再把runner提交給parent(Executor),parent再取出1個空閑線程運行runner,這個runner又獨占了這個線程。