【问题标题】:Sleeping a thread inside an ExecutorService (Java/Clojure)在 ExecutorService (Java/Clojure) 中休眠一个线程
【发布时间】:2011-03-22 21:17:27
【问题描述】:

我在 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 的论点?如果我理解正确,在这种情况下,我的每个工人都有自己的线程,因此应该没有副作用。

如果 Executor 使用的是 FixedThreadPool:

(Executors/newFixedThreadPool 1000)

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

我对这个实例中的线程的理解正确吗?

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

【问题讨论】:

    标签: java multithreading clojure jvm executorservice


    【解决方案1】:

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

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

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

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

    Clojure 的另一种选择是显式地将工作线程放入由 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.
    

    【讨论】:

      【解决方案2】:

      休眠线程的另一种方法是让每个工作人员都有一个“sleepUntil”长值。当你的执行者调用一个工人时,如果它正在睡觉,它会立即返回。否则,它会完成它的工作,然后返回。这有助于减少线程计数,因为 FixedThreadPoolExecutor 将能够处理比它拥有的线程更多的工作线程,如果它们中的大多数被标记为睡眠并快速返回。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-18
        • 1970-01-01
        • 2014-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多