rou*_*ble 5 java multithreading design-patterns timer executorservice
从我的读数来看,似乎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
}
Run Code Online (Sandbox Code Playgroud)
tia,卢布
这看起来像一个问题:
private boolean startTimer() {
// ......
if (_TimerFuture != null) {
_TimerFuture.cancel(false);
}
_TimerFuture = _Timer.schedule(new TimerPopTask(),
TIMER_IN_SECONDS,
TimeUnit.SECONDS);
// ......
}
Run Code Online (Sandbox Code Playgroud)
由于您传递 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;
}
}
Run Code Online (Sandbox Code Playgroud)
那么我将保留 的实例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;
}
}
Run Code Online (Sandbox Code Playgroud)
(与 stopTimer() 方法类似的修改。)
如果您确实预计需要在当前计时器到期之前“重新启动”计时器,您可能需要增加线程数:
private ScheduledExecutorService _Timer = Executors.newScheduledThreadPool(5);
Run Code Online (Sandbox Code Playgroud)
您可能想要采用混合方法,保留对我所描述的当前 TimerPopTask 和当前 ScheduledFuture 的引用,并尽最大努力取消它并释放线程(如果可能),并理解它不能保证取消。
(注意:这一切都假设 startTimer() 和 stopTimer() 方法调用仅限于单个主线程,并且只有实例TimerPopTask在线程之间共享。否则您将需要额外的保护措施。)
| 归档时间: |
|
| 查看次数: |
4859 次 |
| 最近记录: |