![](/img/trans.png)
[英]Start & Stop a ScheduledExecutorService in Java EE environment using servlet
[英]using ScheduledExecutorService to start and stop timer
从我的读数来看,似乎ScheduledExecutorService是在Java中启动和停止计时器的正确方法。
我需要移植一些启动和停止计时器的代码。 这不是周期性计时器。 此代码在启动之前停止计时器。 所以,实际上每次启动都是一次重启()。 我正在寻找使用ScheduledExecutorService执行此操作的正确方法。 这就是我想出的。 寻找有关我缺少的事情的评论和见解:
ScheduledExecutorService _Timer = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> _TimerFuture = null;
private boolean startTimer() {
try {
if (_TimerFuture != null) {
//cancel execution of the future task (TimerPopTask())
//If task is already running, do not interrupt it.
_TimerFuture.cancel(false);
}
_TimerFuture = _Timer.schedule(new TimerPopTask(),
TIMER_IN_SECONDS,
TimeUnit.SECONDS);
return true;
} catch (Exception e) {
return false;
}
}
private boolean stopTimer() {
try {
if (_TimerFuture != null) {
//cancel execution of the future task (TimerPopTask())
//If task is already running, interrupt it here.
_TimerFuture.cancel(true);
}
return true;
} catch (Exception e) {
return false;
}
}
private class TimerPopTask implements Runnable {
public void run () {
TimerPopped();
}
}
public void TimerPopped () {
//Do Something
}
tia,卢布
这看起来像一个问题:
private boolean startTimer() {
// ......
if (_TimerFuture != null) {
_TimerFuture.cancel(false);
}
_TimerFuture = _Timer.schedule(new TimerPopTask(),
TIMER_IN_SECONDS,
TimeUnit.SECONDS);
// ......
}
由于您要传递false以取消,因此如果任务已在运行,则旧的_TimerFuture
可能不会被取消。 无论如何都会创建一个新的(但它不会同时运行,因为您的ExecutorService
的固定线程池大小为1)。 在任何情况下,这听起来都不像您在调用startTimer()时重新启动计时器所需的行为。
我会重新解构一下。 我会让TimerPopTask
实例成为你“取消”的东西,我会在创建后单独保留ScheduledFutures
:
private class TimerPopTask implements Runnable {
//volatile for thread-safety
private volatile boolean isActive = true;
public void run () {
if (isActive){
TimerPopped();
}
}
public void deactivate(){
isActive = false;
}
}
那么我会保留TimerPopTask
的实例,而不是ScheduledFuture
的实例,并重新排列startTimer方法:
private TimerPopTask timerPopTask;
private boolean startTimer() {
try {
if (timerPopTask != null) {
timerPopTask.deactivate();
}
timerPopTask = new TimerPopTask();
_Timer.schedule(timerPopTask,
TIMER_IN_SECONDS,
TimeUnit.SECONDS);
return true;
} catch (Exception e) {
return false;
}
}
(对stopTimer()方法的类似修改。)
如果您确实需要在当前计时器到期之前“重新启动”计时器,则可能需要增加线程数:
private ScheduledExecutorService _Timer = Executors.newScheduledThreadPool(5);
您可能希望采用混合方法,保持对我所描述的当前TimerPopTask和当前ScheduledFuture的引用,并尽可能取消它并尽可能释放线程,理解它不能保证取消。
(注意:这都假定startTimer()和stopTimer()方法调用仅限于一个主线程,并且只有线程之间共享TimerPopTask
实例。否则,您将需要额外的安全措施。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.