目标:
最后入队okhttp3.Call
的先执行
尝试过的解决方案:LIFO Executor
(不起作用)
我找到了一个 LIFO 的解决方案Executor
(带有 LIFO 排序的执行器服务),并通过这种方式将这种应用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
“ - 然后,这些
Call
s按FIFO顺序从readyAsyncCalls
阻塞双端队列中移出Executor
- 最后,
Call
s in以LIFO顺序Executor
执行
就我而言,同时产生了巨大Call
的 s,并且消耗它们的线程相对较少。
--> 大部分Call
s都在排队Dispatcher
而不是Executor
在某一刻
--> LIFOExecutor
不发挥效果
例子
| 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 |
Call
s 以 FIFO 顺序从Dispatcher
到移动Executor
,这个过程非常“低效”。Call
从Executor
执行状态到执行状态的顺序是 LIFO 顺序。Call
但是s中的s很少Executor
,LIFO效果不明显。
有谁知道实现这一目标的其他方法?