为什么ScheduledThreadPoolExecutor的队列大小始终为0?

时间:2017-05-15 15:57:58

标签: java multithreading scala threadpoolexecutor scheduledexecutorservice

我正在使用ScheduledThreadPoolExecutor每毫秒安排一项任务。据我所知,ScheduledThreadPoolExecutor在内部使用无界队列,并在没有任何线程可用于执行时附加任务。

结果我假设如下:如果我有一个具有单个线程的执行程序,并且定期运行的任务所花费的时间比调度的频率长,那么队列大小会不断增加。不知何故,这似乎不正确,但我的下面的最小代码示例:

import java.util.concurrent.{ScheduledThreadPoolExecutor, TimeUnit}

object MinimalExample {

  val numberOfThreads = 1
  val executor = new ScheduledThreadPoolExecutor(numberOfThreads)

  def execute(): Unit = {
    val thread = new TestThread(executor)
    val initialDelay = 0
    val interval = 1
    executor.scheduleAtFixedRate(thread, initialDelay, interval, TimeUnit.MILLISECONDS)
  }

  def main(args: Array[String]): Unit = {
    execute()
  }
}

class TestThread(executor: ScheduledThreadPoolExecutor) extends Runnable {
  override def run(): Unit = {
    Thread.sleep(2000)
    println("just slept 2 seconds")
    println(s"queue size: ${executor.getQueue().size()}")
  }
}

它总是为队列的大小打印0。如果任务花费超过2秒并且每毫秒安排一次,那怎么可能呢?我错过了什么吗?

1 个答案:

答案 0 :(得分:2)

在执行定期任务时,将从内部队列中将其删除(resources :payments do get 'pay', on: :member end -n或take()-ed)。任务成功完成后,将重新添加它。 (或者,如果引发异常,则不会。)这同时适用于poll()scheduleWithFixedDelayscheduleAtFixedRate返回内部任务等待的队列。此队列还包含等待其延迟到期的延迟任务,但不包含当前正在执行的任务。 (使用getQueue进行查询。)

将Javadoc引用为getActiveCount

  

如果此任务的执行时间超过其执行时间,则随后的执行可能会 late 开始,但不会同时执行。

这是通过仅在执行之后将定期任务重新添加到队列中来完成的。任务本身在执行期间不会出现在队列中,也不会多次出现在队列中。