为什么 ScheduledThreadPoolExecutor 的队列大小总是 0?
Why is the queue size of a ScheduledThreadPoolExecutor always 0?
我正在使用 ScheduledThreadPoolExecutor
每毫秒安排一个任务。据我了解,ScheduledThreadPoolExecutor
在内部使用无界队列,并在 none 线程可用于执行任务时附加任务。
因此,我假设如下:如果我有一个单线程的执行程序,并且周期性 运行 的任务花费的时间比计划的频率长,那么队列大小会增加不断地。尽管对于我的以下最小代码示例,这似乎并不正确:
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 秒并且每毫秒安排一次,那怎么可能呢?我错过了什么吗?
在执行周期性任务时,它会从内部队列中删除(take()
-n 或 poll()
-ed)。当任务成功完成后,它会在稍后重新添加。 (如果它抛出异常,则不会。)这适用于 scheduleWithFixedDelay
和 scheduleAtFixedRate
。 getQueue
returns 内部任务队列 正在等待 执行。该队列还包含等待延迟到期的延迟任务,但不包含当前正在执行的任务。 (使用 getActiveCount
查询。)
引用 scheduleAtFixedRate
的 javadoc:
If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
这是通过仅在周期性任务执行后将其重新添加到队列中来完成的。任务本身在执行期间不会出现在队列中,并且永远不会出现在队列中多次。
我正在使用 ScheduledThreadPoolExecutor
每毫秒安排一个任务。据我了解,ScheduledThreadPoolExecutor
在内部使用无界队列,并在 none 线程可用于执行任务时附加任务。
因此,我假设如下:如果我有一个单线程的执行程序,并且周期性 运行 的任务花费的时间比计划的频率长,那么队列大小会增加不断地。尽管对于我的以下最小代码示例,这似乎并不正确:
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 秒并且每毫秒安排一次,那怎么可能呢?我错过了什么吗?
在执行周期性任务时,它会从内部队列中删除(take()
-n 或 poll()
-ed)。当任务成功完成后,它会在稍后重新添加。 (如果它抛出异常,则不会。)这适用于 scheduleWithFixedDelay
和 scheduleAtFixedRate
。 getQueue
returns 内部任务队列 正在等待 执行。该队列还包含等待延迟到期的延迟任务,但不包含当前正在执行的任务。 (使用 getActiveCount
查询。)
引用 scheduleAtFixedRate
的 javadoc:
If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
这是通过仅在周期性任务执行后将其重新添加到队列中来完成的。任务本身在执行期间不会出现在队列中,并且永远不会出现在队列中多次。