3

如何使用以下属性完成“等待空闲”模型:

  • 当一个方法do()被调用时,经过X延迟,一个close()方法会被调用。
  • 如果我在X 时间过去之前do()再次调用该方法,则必须推迟调用 to。close()

例子

场景 1:(超时 = 10 秒):

  1. do()用户按时打电话0
  2. 在 time 10,该close()方法被调用是因为用户没有do()再次调用。

场景 2:(也超时 = 10 秒):

  1. do()用户按时打电话0。(所以应该调用10该方法)。close()
  2. 8,用户再次呼叫do()
  3. 10什么都没有发生的时候,因为close()被推迟了 10 秒。
  4. 在 时间18,该close()方法被调用,因为用户do()自 以来没有再次调用8

我试过的:

private static final long delay = 10000;
private Timer t;
private TimerTask tt;

public void do() {

    ...

    // check old timer first:
    if (t != null) t.cancel();

    // create new timer
    t = new Timer();
    tt = new TimerTask() {
        @Override
        public void run() {
            close();
        }
    }
    // run it
    t.schedule(tt, System.currentTimeMillis() + delay);
}
private void close() {
    // do some cleanup here
}

这段代码非常难看。它也非常低效且消耗内存,因为该 do()函数每秒被调用大约 50 次。

我应该怎么做才能以一种高效而整洁的方式工作?(真的有那么难吗?)

4

3 回答 3

4

你走在正确的道路上,这并不难。

这就是我想给你的建议。只创建一次计时器。使其成为班级成员。在构造函数中创建它的实例。

当方法被调用时,就像你现在已经做的那样创建一个任务。但是,您可以创建单独的类,甚至可以提前创建它的实例,并且在do()调用方法时只需安排它,因此close()将根据您的时间表调用。

何时do()调用取消先前创建的关闭任务。这将确保在do()再次调用方法时不会关闭任何内容。

顺便说一句,因为do它是 java 中的保留字,所以您不能以这种方式调用方法。这意味着您的代码甚至无法编译。更改名称。

于 2013-03-21T20:19:12.287 回答
1

设置一个 10 秒的定时器任务,当你open()

保留一个变量,该变量long lastCall设置为System.currentTimeMillis()fromdoIt()

在时间任务体中,检查是否lastCall在 10 秒内。如果是这样,重新安排定时器任务的剩余时间。如果没有,请致电close()

synchronize当你阅读或写作时,不要忘记在某事上lastCall

于 2013-03-21T20:26:59.293 回答
0

我找到了一个合适的解决方案:

public class TimerExample {

    private TimerTask tt;
    ScheduledFuture<?> future;
    private ScheduledThreadPoolExecutor s;

    public TimerExample() {
        s = new ScheduledThreadPoolExecutor(1);
        tt = new TimerTask() {

            @Override
            public void run() {
                close();
            }
        };
        doSomething();
    }

    public void doSomething() {
        if (future != null) future.cancel(true);
        future = s.schedule(tt, 3000, TimeUnit.MILLISECONDS);
        System.out.println("do");
    }

    public void close() {
        System.out.println("Close");
    }

}
于 2013-03-21T21:08:54.107 回答