Multithreading future是否总是创建新线程?

Multithreading future是否总是创建新线程?,multithreading,clojure,future,Multithreading,Clojure,Future,假设我这样做: (future (do-the-thing)) 我是否可以保证,无论(做事情)做什么 将创建一个全新的线程,而不是从池或类似的地方获取线程 除了(执行该操作)之外,没有其他东西会在新线程上运行 一旦(执行操作)在新线程上执行,线程将终止吗 如果不是,在什么情况下这些假设是错误的?简短的回答是否 来自clojure的: 因此未来的执行者是clojure.lang.Agent/soloExecutor 发件人: 您可以看到,soloExecutor是由执行者创建的。newC

假设我这样做:

(future
  (do-the-thing))
我是否可以保证,无论
(做事情)
做什么

  • 将创建一个全新的线程,而不是从池或类似的地方获取线程
  • 除了
    (执行该操作)
    之外,没有其他东西会在新线程上运行
  • 一旦
    (执行操作)
    在新线程上执行,线程将终止吗

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

简短的回答是

来自clojure的:

因此未来的执行者是
clojure.lang.Agent/soloExecutor

发件人:

您可以看到,
soloExecutor
是由执行者创建的。newCachedThreadPool()

发件人:

创建一个线程池,该线程池根据需要创建新线程,但在以前构造的线程可用时将重用这些线程。这些池通常会提高执行许多短期异步任务的程序的性能。调用execute将重用以前构造的线程(如果可用)。如果没有可用的现有线程,将创建一个新线程并将其添加到池中。六十秒未使用的线程将被终止并从缓存中删除。因此,空闲时间足够长的池不会消耗任何资源。请注意,可以使用ThreadPoolExecutor构造函数创建具有类似属性但详细信息不同(例如超时参数)的池

因此,答案是
(执行该操作)
的其他作业可能在同一线程中执行,如果没有其他作业,则该线程将在60秒后终止

您可以在以下代码中确认执行器的行为。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
50 49 43 41 45 42 46 47 48 44 nil
60 59 58 57 56 55 54 53 52 51 nil
第一次。并在5秒后再次执行,得到:

50 49 48 47 46 45 44 43 42 41 nil
50 49 43 41 45 42 46 47 48 44 nil
60 59 58 57 56 55 54 53 52 51 nil
因此,您可以确认线程是否被重用

如果在60秒后执行相同的代码,则会得到:

50 49 48 47 46 45 44 43 42 41 nil
50 49 43 41 45 42 46 47 48 44 nil
60 59 58 57 56 55 54 53 52 51 nil

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

我的理解是,Clojure中的未来在不使用专用库时只不过是Java未来。所以这可能已经作为Java问题被询问和回答了。@ChrisMurphy如果你能将我链接到Java问题,那就太好了!Java期货阻止,而Scala期货则不阻止。然而,Clojure中的这个缺点已经用这个解决了。@ChrisMurphy我不明白这和我的问题有什么关系。你能解释一下吗?我想@ymonad很好地回答了你的问题。我想补充的一点是,即使它的实现方式有所不同,您也不应该在任何重要的事情上依赖它。AFAIK这是一个没有文档记录的实现细节,它在将来总是会改变,并且会破坏任何依赖于特殊行为的代码。如果你真的需要一个线程,那么就买一个真正的Java线程。以防万一人们感兴趣:
core.async
使用
newFixedThreadPool