gpt4 book ai didi

multithreading - future 总是创建一个新线程吗?

转载 作者:行者123 更新时间:2023-12-01 00:44:19 26 4
gpt4 key购买 nike

假设我这样做:

(future
(do-the-thing))

我保证,不管怎样 (do-the-thing)做,
  • 将创建一个全新的线程,而不是从池中获取一个线程或类似的东西?
  • 除了(do-the-thing)会在那个新线程上运行吗?
  • 一次 (do-the-thing)在那个新线程上执行,线程会终止吗?

  • 如果不是,在什么情况下这些假设是错误的?

    最佳答案

    简短的回答是

    来自clojure的core.clj :

    (defmacro future
    ...
    [& body] `(future-call (^{:once true} fn* [] ~@body)))
    ...

    (defn future-call
    ...
    [f]
    (let [f (binding-conveyor-fn f)
    fut (.submit clojure.lang.Agent/soloExecutor ^Callable f)]
    ...

    所以 future 的执行者是 clojure.lang.Agent/soloExecutor .

    来自 Agent.java :
    volatile public static ExecutorService soloExecutor = Executors.newCachedThreadPool(
    createThreadFactory("clojure-agent-send-off-pool-%d", sendOffThreadPoolCounter));

    你可以看到 soloExecutorExecutors.newCachedThreadPool() 创建

    来自 document of Executors.newCachedThreadPool :

    Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available. These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks. Calls to execute will reuse previously constructed threads if available. If no existing thread is available, a new thread will be created and added to the pool. Threads that have not been used for sixty seconds are terminated and removed from the cache. Thus, a pool that remains idle for long enough will not consume any resources. Note that pools with similar properties but different details (for example, timeout parameters) may be created using ThreadPoolExecutor constructors.



    所以答案是 (do-the-thing) 的其他工作可以在同一个线程中执行,如果没有更多的工作,线程将在 60 秒后终止。

    您可以确认 Executors.newCachedThreadPool的行为在以下代码中:
    (doseq [i (for [x (range 10)] (future (Thread/sleep 1000) (.getId (Thread/currentThread))))] (print @i) (print " "))

    在 clojure 控制台中执行这段代码,你会得到:
    50 49 48 47 46 45 44 43 42 41 nil

    第一次。并在 5 秒后再次执行它,你会得到:
    50 49 43 41 45 42 46 47 48 44 nil

    因此,您可以确认该线程已被重用。

    如果你在 60 秒后执行相同的代码,你会得到:
    60 59 58 57 56 55 54 53 52 51 nil

    因此,您可以确认先前的线程已终止并创建了新线程。

    关于multithreading - future 总是创建一个新线程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35641757/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com