java - 为什么 Java 的 scheduleWithFixedDelay 使用 Runnable 而不是 FutureTask<?> 包装 runnable?

标签 java concurrency scheduled-tasks

为什么 Java 的 scheduleWithFixedDelay 使用 Runnable 而不是包装 runnable 的 FutureTask?

这可以很容易地用两个不同的代码示例来展示:

ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleWithFixedDelay(new FutureTask<Integer>(new Callable<Integer>() {

            @Override
            public Integer call() throws Exception {
                System.out.println("beep");
                return 1;
            }
        }), 1, 5, TimeUnit.SECONDS);

产生:

beep

但是应用程序并没有退出,它只是在等待。

但是:

ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    executorService.scheduleWithFixedDelay(new Runnable() {

        @Override
        public void run() {
            System.out.println("beep ");
        }
    }, 1, 5, TimeUnit.SECONDS);

产生:

哔哔声 嘟 嘟 嘟 哔哔声

以 5 秒为间隔。

似乎这里发生了某种我无法确定的锁。

最佳答案

因为您有点滥用 FutureTask

根据 Javadocs,FutureTask 是“可取消的异步计算”,但更通俗地说,它包装了 Runnable/Callable 的特定执行以提供异步性。在我刚才检查之前,我实际上并没有意识到它实现了 Runnable - run() 的实现“将这个 Future 设置为它的计算结果”。

所以在你的第一个例子中发生的事情是你正在安排 future 的任务,它的运行方法在 1 秒后被调用,因此它计算计算结果(即运行嵌入的 Runnable ).当此方法退出时,FutureTask 现已运行并获得其具体结果 - 因此 future 对 run() 的调用是空操作。

我认为这里的根本问题是直接安排 FutureTask 似乎没有意义,至少不是以您在这里所做的方式。如果您希望一段代码每五秒运行一次,那么您绝对应该采用第二种方法。 FutureTask 包含一个(单个!)计算;您没有理由希望它被多次调用,实际上它专门缓存了结果以防止这种情况发生。

关于java - 为什么 Java 的 scheduleWithFixedDelay 使用 Runnable 而不是 FutureTask<?> 包装 runnable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3197114/

相关文章:

python - 在 Python 应用程序中安排日常任务

java - 从数据库读取时出现"Invalid cursor state"错误

java - cachedThreadPool 没有按我的预期工作

node.js - 每月限制 Heroku dyno 一天

javascript - Javascript 中是否有 "immediate events"之类的东西?

sql - 如何在SQL Server上模拟DEADLOCK?

python - 为 python 脚本(bot)启动预定作业的最佳方式

java - 如何实现 Ctrl + 单击

java - 创建两副相同但不同的牌,并同时从中抽取

java - Maven 和 Eclipse 问题——寻找资源