Java “真的这么难吗?”;推迟;任务(或“等待空闲”)
如何使用以下属性实现“等待空闲”模型:Java “真的这么难吗?”;推迟;任务(或“等待空闲”),java,timer,scheduled-tasks,Java,Timer,Scheduled Tasks,如何使用以下属性实现“等待空闲”模型: 当调用方法do()时,在X延迟之后,将调用close()方法 如果在X时间过去之前再次调用do()方法,则对close()的调用必须推迟 示例 场景1:(对于超时=10秒): 用户在时间0调用do() 在时间10时,调用close()方法,因为用户没有再次调用do() 场景2:(同时超时=10秒): 用户在时间0调用do()。(因此在10中,应该调用close()方法) 在8时,用户再次调用do() 在10时,由于close()延迟了10秒,因此没有发
- 当调用方法
时,在X延迟之后,将调用do()
方法close()
- 如果在X时间过去之前再次调用
方法,则对do()
的调用必须推迟close()
0
调用do()
10
时,调用close()
方法,因为用户没有再次调用do()
0
调用do()。(因此在10
中,应该调用close()
方法)
8
时,用户再次调用do()
10
时,由于close()
延迟了10秒,因此没有发生任何事情18
时,调用close()
方法,因为自8
以来,用户没有再次调用do()
do()
函数每秒被调用大约50次
我应该怎么做才能使它高效、整洁地工作?(这真的很难吗?你走的路是对的,不是很难 这是我想给你的建议。只创建一次计时器。让它成为班级的一员。在构造函数中创建其实例 当方法被调用时,按您现在所做的方式创建任务。但是,您可以创建单独的类,甚至可以提前创建它的实例,当调用
do()
方法时,只需对其进行调度,因此将根据您的调度调用close()
调用do()
时,取消先前创建的关闭任务。这将确保在再次调用方法do()
时不会关闭任何内容
顺便说一句,因为在java中,
do
是一个保留字,所以不能用这种方式调用该方法。这意味着您的代码甚至无法编译。更改名称。在打开()时设置10秒计时器任务。
保留一个变量long lastCall
,该变量从doIt()
在时间任务正文中,检查lastCall
是否在10秒内。如果是,请重新安排计时器任务的剩余时间。如果没有,请调用close()
当您从
lastCall
读写时,请不要忘记对某些内容进行同步
,我找到了一个合适的解决方案:
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");
}
}
公共类TimerExample{
专用定时器任务tt;
计划未来;
私有调度线程池执行器;
公共TimerExample(){
s=新的ScheduledThreadPoolExecutor(1);
tt=新时间任务(){
@凌驾
公开募捐{
close();
}
};
doSomething();
}
公共无效剂量测定法(){
如果(future!=null)future.cancel(true);
future=s.schedule(tt,3000,时间单位毫秒);
System.out.println(“do”);
}
公众假期结束(){
系统输出打印项次(“关闭”);
}
}
为什么要一次又一次地创建计时器?您应该重复使用一个计时器,并且只取消/安排其上的任务。当你解决这个问题时,就不会有任何低效和内存消耗了。线程“main”java.lang.IllegalStateException中的异常:任务已经调度或取消了
@MarkoTopolnik-你不能在已经取消的计时器上调度任务。@Perception当然。这就是为什么你不取消计时器。您取消了任务。@MarkoTopolnik-没关系,我知道您在哪里陈述了任务与计时器。我明白了,但是我不完全理解第三段,我应该在do()方法中做什么(以及在单独的类中做什么)?(命名只是因为我直接编写了代码,没有考虑到这一点)。
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");
}
}