为什么 ScheduledExecutorService 没有按预期工作?

发布于 2025-01-13 11:12:05 字数 958 浏览 0 评论 0原文

我正在创建一个 10 个线程的池 每个线程运行3秒 我将每个任务的启动周期设置为0.5秒

问题是,如果池由10个线程组成,启动周期为0.5秒,为什么从第一个线程启动第二个线程需要3秒? 毕竟,10 个线程应该在 0.5 秒内同时启动,依此类推。

如果我使用 newSingleThreadScheduledExecutor 这是可以理解的,但我使用的是带有 10 个线程的 newScheduledThreadPool。

public class Main17 {

    public static void main(String[] args) {

        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
        Runnable r = ()-> {
            System.out.println("hello "+System.currentTimeMillis());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        scheduledExecutorService.scheduleAtFixedRate(r,0, 500, TimeUnit.MILLISECONDS);

    }
}

结果

hello 1646991199804
hello 1646991202816     // Interval greater than 0.5 seconds
hello 1646991205831
hello 1646991208840
hello 1646991211850

I am creating a pool of 10 threads
Each thread runs for 3 seconds
I set the startup period of each task to 0.5 seconds

The question is, if the pool consists of 10 threads, and the startup period is 0.5 seconds, why does it take 3 seconds from the first thread to start the second one?
After all, 10 threads should start in 0.5 seconds at once, and so on.

If I were to use newSingleThreadScheduledExecutor it would be understandable, but I'm using newScheduledThreadPool with 10 threads.

public class Main17 {

    public static void main(String[] args) {

        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
        Runnable r = ()-> {
            System.out.println("hello "+System.currentTimeMillis());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        scheduledExecutorService.scheduleAtFixedRate(r,0, 500, TimeUnit.MILLISECONDS);

    }
}

result

hello 1646991199804
hello 1646991202816     // Interval greater than 0.5 seconds
hello 1646991205831
hello 1646991208840
hello 1646991211850

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

追星践月 2025-01-20 11:12:05

线程在这里不起作用。您必须了解您正在使用的方法的效果。

scheduleAtFixedRate(Runnable command,长初始延迟,长周期,TimeUnit单位)

创建并执行一个周期性操作,该操作首先在给定的初始延迟后启用,然后在给定的周期内启用;也就是说,执行将在initialDelay之后开始,然后是initialDelay+period,然后是initialDelay + 2 * period,依此类推。如果任务的任何执行遇到异常,则后续执行将被抑制。否则,任务只会通过取消或终止执行器来终止。

重要部分:

如果此任务的任何执行时间超过其周期,则后续执行可能会延迟开始,但不会同时执行。

执行器等待 500ms 的间隔或可运行对象的执行时间,以较长者为准。在您的情况下,这是运行可运行程序的时间,因此时间戳的差异恰好是 3 秒。

编辑:您可以查看这篇文章,其中有人遇到了同样的问题。有两个答案可以达到您想要的结果。

The threads have no effect here. You have to understand the effect of th method you are using.

Documentation for scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit):

Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on. If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor.

Important part:

If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.

The executor waits either the interval of 500ms or the execution time of the runnable, whichever is longer. In your case, it is the time to run the runnable and therefore the difference in your timestamps is exactly 3 seconds.

EDIT: You can look at this post, where someone had the same problem. There are two answers that achieve your desired result.

终弃我 2025-01-20 11:12:05

引用ScheduledExecutorService.scheduleAtFixedRate()官方文档:

如果此任务的任何执行时间超过其周期,则后续执行可能会延迟开始,但不会同时执行。

来源:ScheduledExecutorService 文档

Quoting the Oficial documentation of ScheduledExecutorService.scheduleAtFixedRate():

If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.

Source: ScheduledExecutorService documentation

柳若烟 2025-01-20 11:12:05

请参阅 ScheduleAtFixedRate jdk 文档

块引用
如果此任务的任何执行时间超过其周期,则后续执行可能会延迟开始,但不会同时执行。
块引用

您的任务至少需要 3 秒才能完成。

see the scheduleAtFixedRate jdk doc

Blockquote
If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
Blockquote

Your task need at least 3 second to complete.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文