ゴール:
最後にエンキューokhttp3.Call
されたものが最初に実行される
試した解決策:LIFO Executor
(機能しない)
Executor
私はLIFO (LIFO順序付けのExecutor Service )の解決策を見つけ、この方法でこの種のものを適用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 が同時に生成され、それらを消費するスレッドは比較的少なくなります。
--> ほとんどの s は、一時的
にではなくCall
キューに入れられます--> LIFOは効果を再生しませんDispatcher
Executor
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 |
Call
s は FIFO 順で からDispatcher
に移動されExecutor
ますが、この手順は非常に「非効率的」です。Call
■ からExecutor
実行状態までは LIFO 順です。Call
しかし にはsが少なくExecutor
、LIFO 効果は明らかではありません。
これを達成する他の方法を知っている人はいますか?