たごもりすメモ

コードとかその他の話とか。

okhttpで非同期リクエストを実行するとき実行スレッドはどうなっているのか

複数のホストに並行してHTTPリクエストを送るコードをJavaで書く必要があって、Undertowをサーバに使ってるんでUndertowの http client でもいいかなーと思ってたんだけど、okhttpにも非同期リクエストの機能があるみたい。

ただパッと見て実行スレッド数の設定とかどうなっとるんや、というのが全くわかんなかったのでちょっとコードを追ってみたところ、以下のような感じのコードを発見しました。
呼び出し順としてはの以下ような感じ。

  • OkHttpClient.newCall(Request req)
  • Call.enqueue(Callback callback)
  • RealCall.enqueue(Callback callback)
  • client.dispatcher().enqueue(new AsyncCall(responseCallback)); ココ

なんで、この dispatcher() で返ってくるやつの正体を見ればどう制御してるかわかるだろ、って追ってみたらこんな。

https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/Dispatcher.java#L63

  public synchronized ExecutorService executorService() {
    if (executorService == null) {
      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
  https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/Dispatcher.java#L63}

ThreadPoolExecutorの引数は corePoolSize, maximumPoolSize, ... なので、なんかもう無限に(ではないけど)スレッド作る感じですね! 気合いが入っている!!

で、これはねーなと思いかけたんだけどちょい上のほうを見ると Dispatcher(ExecutorService executorService) というコンストラクタがあるので、外で設定済みのexecutorServiceを渡してDispatcherを作り、それを OkHttpClient.Builder.dispatcher() に渡して build() すれば設定済みクライアントが作れそう。
ちょっとめんどいな。