與JAVA Executor的區(qū)別
vertx框架提供了OrderedExecutor的實現(xiàn)雇初,其能保證提交的任務(wù)按照嚴格的提交順序執(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)標志。
首先分析runner血当,其運行的任務(wù)是個循環(huán)任務(wù)幻赚,只有當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相當于1個線程池,但每個OrderedExecutor在運行狀態(tài)會獨占1個線程弯蚜,因為在把runner提交給parent執(zhí)行時孔轴,parent會選出1個空閑線程執(zhí)行該runner,而該runner是個循環(huán)任務(wù)碎捺,會獨占這個線程路鹰。
OrderedExecutor通過1個runner任務(wù)處理所有提交到該OrderedExecutor的runnable,當處理完tasks中所有任務(wù)后就把線程歸還給parent(Executor)收厨,當下次有新的runnable提交進來時再把runner提交給parent(Executor)晋柱,parent再取出1個空閑線程運行runner,這個runner又獨占了這個線程诵叁。