gpt4 book ai didi

java - 在 ExecutorService 中 hibernate 一个线程 (Java/Clojure)

转载 作者:搜寻专家 更新时间:2023-10-31 19:58:20 25 4
gpt4 key购买 nike

我在 clojure 程序中创建了大量线程:

(import '(java.util.concurrent Executors)) 
(def *pool*
(Executors/newCachedThreadPool))

(defn do-something []
; work
Thread/sleep 200
; repeat)

(dotimes [i 10000]
(.submit *pool* do-something))

对我来说,使用 JVM 已经有一段时间了,我基本上想知道是否有任何反对在 Executor 执行的函数中使用 sleep 或 yield 的争论?如果我理解正确,在这种情况下,我的每个 worker 都有自己的线程,因此应该没有副作用。

如果执行器使用固定线程池:

(Executors/newFixedThreadPool 1000)

事情变得更加复杂,因为线程在工作完成之前不会返回到池中,这意味着如果线程正在 hibernate ,其他排队的工作人员将需要更长的时间才能完成。

在这种情况下,我对线程的理解是否正确?

(注意:我怀疑我的设计实际上是错误的,但只是想确保我在正确的页面上)

最佳答案

执行器在概念上是一个任务队列+一个工作池。你对这里会发生什么的解释基本上是正确的。当您将任务提交给执行程序时,工作将被排队,直到线程可以执行该任务。当它正在执行任务时,该任务拥有线程并且 sleep 将阻止其他任务在该工作线程上执行。

根据您正在做的事情,这可能没问题(尽管在任务中 sleep 是不寻常的,而且可能是不好的形式)。阻塞线程作为等待 IO 的副作用更为常见(例如,阻塞在套接字或数据库调用上)。

通常,如果您正在进行周期性工作,最好在池外处理并在应该执行任务时触发任务,或者更好的是,使用 ScheduledExecutorService而不是来自 Executors/newScheduledThreadPool。

Java 中用于执行基于时间的任务的另一个主要机制是 java.util.Timer ,它更易于使用,但不如 ScheduledExecutorService 强大。

Clojure 的另一种替代方法是显式地将 worker 放入由 Clojure 而不是您管理的后台线程中:

(defn do-task [] 
(println (java.util.Date.) "doing task"))

(defn worker [f n wait]
(doseq [task (repeat n f)]
(f)
(Thread/sleep wait)))

;; use future to execute worker in a background thread managed by Clojure
(future (worker do-task 10 1000))

;; the call to future returns immediately but in the background console
;; you will see the tasks being run.

关于java - 在 ExecutorService 中 hibernate 一个线程 (Java/Clojure),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5397955/

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