【发布时间】:2020-02-28 14:20:40
【问题描述】:
目标:
最后入队的okhttp3.Call首先执行
尝试过的解决方案:LIFO Executor(不起作用)
我找到了 LIFO Executor(Executor Service with LIFO ordering) 的解决方案,并通过这种方式将这种 Executor 应用到 OkHttpClient 中
private val httpClient = OkHttpClient.Builder().dispatcher(
Dispatcher(ThreadPoolExecutor(..., LifoLinkedBlockingDequeue<Runnable>()))
).build()
但是,这不起作用。
分析
在okhttp3.Dispatcher追踪源码后发现:
- 首先,每个入队的
Call被添加到(private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>())中的Dispatcher.java" - 然后,那些
Calls 从readyAsyncCalls移动到Executor的阻塞双端队列中以FIFO 顺序 - 最后,
Executor中的Calls 以LIFO顺序执行
在我的例子中,大量的Calls 是同时产生的,并且消耗它们的线程相对较少。
--> 大多数Calls 暂时排在Dispatcher 而不是Executor
--> LIFO Executor 不起作用
示例
| Dispatcher: 1,2,3,4,5 | Executor: | executing: | done: |
| Dispatcher: 2,3,4,5 | Executor:1 | executing: | done: |
| Dispatcher: 4,5 | Executor:2,3 | executing:1 | done: |
| Dispatcher: 5 | Executor:4 | executing:3,2 | done:1 |
| Dispatcher: | Executor:5 | executing:4 | done:1,3,2 |
| Dispatcher: | Executor: | executing:5 | done:1,3,2,4 |
| Dispatcher: | Executor: | executing: | done:1,3,2,4,5 |
-
Calls 以先进先出的顺序从Dispatcher移动到Executor,这个过程非常“低效”。 -
从
Executor到执行状态的Calls 以LIFO 顺序排列。但是Executor中的Calls很少,LIFO效果不明显。
有没有人知道其他方法来实现这一点?
【问题讨论】:
标签: android okhttp requestdispatcher lifo