先物でテストを実行すると、次のことがわかりました。
user=> (time (doall (map deref (for [i (range 1000)]
#_=> (future (Thread/sleep 1000))))))
"Elapsed time: 32058.208 msecs"
2 の累乗が表示されると、頭の中で警鐘が鳴っています。これは、32 個のスレッドしか開始されていないようなにおいがします。
いくつかのターゲットを絞った実験:
user=> (time (doall (map deref (for [i (range 32)]
#_=> (future (Thread/sleep 1000))))))
"Elapsed time: 1002.302 msecs"
(nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil)
user=> (time (doall (map deref (for [i (range 64)]
#_=> (future (Thread/sleep 1000))))))
"Elapsed time: 2004.24 msecs"
(nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil)
user=> (time (doall (map deref (for [i (range 65)]
#_=> (future (Thread/sleep 1000))))))
"Elapsed time: 3005.279 msecs"
(nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil)
これを確認します。32 個の将来のタスクのスライスごとに 1 秒追加されます。
未来を作るコードは
(defmacro future
"Takes a body of expressions and yields a future object that will
invoke the body in another thread, and will cache the result and
return it on all subsequent calls to deref/@. If the computation has
not yet finished, calls to deref/@ will block, unless the variant of
deref with timeout is used. See also - realized?."
{:added "1.1"}
[& body] `(future-call (^{:once true} fn* [] ~@body)))
future-call の興味深い部分は
fut (.submit clojure.lang.Agent/soloExecutor ^Callable f)]
これは次のように変換されます。
volatile public static ExecutorService soloExecutor = Executors.newCachedThreadPool(
createThreadFactory("clojure-agent-send-off-pool-%d", sendOffThreadPoolCounter));
したがって、これは実際に無制限のスレッドプールを作成します。
では、1000 個のスレッドを作成して 1 秒で返すのではなく、32 個のスレッドしか実行していないのはなぜでしょうか?