当前位置: 首页 > 面试题库 >

在一定数量的执行之后如何停止计划重复执行的Runnable

祁修平
2023-03-14
问题内容

情况

我有一个Runnable。我有一个使用ScheduledExecutorService和scheduleWithFixedDelay调度此Runnable执行的类。

目标

我想改变这个班安排了Runnable固定延迟执行 要么 无限期, 直到它已运行一定的次数,取决于被传递给构造函数的参数一些。

如果可能的话,我想使用相同的Runnable,因为从概念上讲应该“运行”相同的东西。

可能的方法

方法1

有两个Runnable,一个在多次执行(保留计数)后取消计划,另一个不执行:

public class MyClass{
    private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    public enum Mode{
        INDEFINITE, FIXED_NO_OF_TIMES
    }

    public MyClass(Mode mode){
        if(mode == Mode.INDEFINITE){
            scheduler.scheduleWithFixedDelay(new DoSomethingTask(), 0, 100, TimeUnit.MILLISECONDS);
        }else if(mode == Mode.FIXED_NO_OF_TIMES){
            scheduler.scheduleWithFixedDelay(new DoSomethingNTimesTask(), 0, 100, TimeUnit.MILLISECONDS);
        }
    }

    private class DoSomethingTask implements Runnable{
        @Override
        public void run(){
            doSomething();
        }
    }

    private class DoSomethingNTimesTask implements Runnable{
        private int count = 0;

        @Override
        public void run(){
            doSomething();
            count++;
            if(count > 42){
                // Cancel the scheduling.
                // Can you do this inside the run method, presumably using
                // the Future returned by the schedule method? Is it a good idea?
            }
        }
    }

    private void doSomething(){
        // do something
    }
}

我宁愿只使用一个Runnable来执行doSomething方法。将调度与Runnable捆绑在一起是错误的。你怎么看待这件事?

方法#2

有一个Runnable来执行我们要定期运行的代码。有一个单独的计划可运行对象,该对象检查第一个可运行对象已运行了多少次,并在达到一定数量时取消。这可能是不准确的,因为它将是异步的。感觉有点麻烦。你怎么看待这件事?

方法#3

扩展ScheduledExecutorService并添加方法
scheduleWithFixedDelayNTimes”。也许这样的类已经存在了?当前,我正在使用Executors.newSingleThreadScheduledExecutor();我的ScheduledExecutorService实例。我大概必须实现类似的功能才能实例化扩展的ScheduledExecutorService。这可能很棘手。你怎么看待这件事?

没有调度程序的方法[编辑]

我无法使用调度程序。我可以改成这样:

for(int i = 0; i < numTimesToRun; i++){
    doSomething();
    Thread.sleep(delay);
}

并在某个线程中运行它。你对那个怎么想的?您可能仍然可以使用runnable并直接调用run方法。

任何建议欢迎。我正在寻找辩论,以找到实现目标的“最佳实践”方法。


问题答案:

您可以在Future上使用cancel()方法。来自scheduleAtFixedRate的javadocs

Otherwise, the task will only terminate via cancellation or termination of the executor

这是一些示例代码,该代码将Runnable包装为另一个,以跟踪原始文件的运行次数,并在运行N次后取消。

public void runNTimes(Runnable task, int maxRunCount, long period, TimeUnit unit, ScheduledExecutorService executor) {
    new FixedExecutionRunnable(task, maxRunCount).runNTimes(executor, period, unit);
}

class FixedExecutionRunnable implements Runnable {
    private final AtomicInteger runCount = new AtomicInteger();
    private final Runnable delegate;
    private volatile ScheduledFuture<?> self;
    private final int maxRunCount;

    public FixedExecutionRunnable(Runnable delegate, int maxRunCount) {
        this.delegate = delegate;
        this.maxRunCount = maxRunCount;
    }

    @Override
    public void run() {
        delegate.run();
        if(runCount.incrementAndGet() == maxRunCount) {
            boolean interrupted = false;
            try {
                while(self == null) {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        interrupted = true;
                    }
                }
                self.cancel(false);
            } finally {
                if(interrupted) {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }

    public void runNTimes(ScheduledExecutorService executor, long period, TimeUnit unit) {
        self = executor.scheduleAtFixedRate(this, 0, period, unit);
    }
}


 类似资料:
  • 问题内容: 我正在写一个如下的shell脚本: 现在,我想要实现的是列出$ ACTIONS_DIR中的每个文件以执行该文件。$ ACTIONS_DIR下的每个文件都是另一个Shell脚本。 现在,这里的问题在于,使用exec之后,脚本将停止并且不会转到下一个文件。任何想法为什么会这样? 问题答案: 替换shell进程。如果只想将该命令作为子进程调用,则将其删除。

  • 问题内容: 是否有可能以某种方式停止或终止JavaScript,从而防止再次发生基于JavaScript的执行,而无需重新加载浏览器? 我在想JavaScript等同于PHP。 问题答案: 简短答案: 如果您想了解更多,请继续阅读。 您是否要停止JavaScript的开发/调试工作? 代码中的表达式将停止页面执行,然后您的浏览器开发人员工具将使您可以查看页面冻结时的状态。 您是否要故意停止设计您的

  • 问题内容: 我使用以下代码在Python中启动并关闭 在脚本结束执行后,我仍然在Mac活动监视器中找到的实例。实际上,每次我运行脚本时,都会创建一个新进程。 我应该如何关闭驱动程序? 问题答案: 不保证该方法释放与驱动程序实例关联的所有资源。请注意,这些资源包括但不限于驱动程序可执行文件(在这种情况下为PhantomJS)。该方法旨在释放驱动程序的所有资源,包括退出可执行进程。

  • 我有一个场景,我需要停止kafka并调用一些函数在消费者停止后执行。同样,flow是这样的: 消费来自kafka主题的消息 将每个消耗的消息添加到文件中 停止kafka监听器,如果它在过去10秒内没有收到任何消息 为Ex调用一些函数:UploadFileToS3() 我在我的消费者方法中使用了spring kafka的@KafkaListener注释。 我知道停止使用@KafkaListener注

  • 我有一个功能,改变货币取决于选择的国家。它只是重定向到相同的页面,但具有不同的值。 脚本: 我想做的第一重定向页面比我想给选择一个国家它有的值。如果选择了俄罗斯而我选择了乌克兰,货币为但选择将停留。我怎么能这样做

  • 本文向大家介绍如何在Oracle中显示SQL执行进度和执行计划?,包括了如何在Oracle中显示SQL执行进度和执行计划?的使用技巧和注意事项,需要的朋友参考一下 问题: 您想查看Oracle SQL在SQL执行计划中花费时间的位置。 解 使用Oracle 11g版本,我们可以在SQL运行时查看SQL执行计划的进度。“ V $SQL_PLAN_MONITOR”视图为SQL语句的执行计划的每个步骤包