我正在尝试使用 java 移植代码timers使用预定执行服务
我有以下用例
class A {
public boolean execute() {
try {
Timer t = new Timer();
t.schedule (new ATimerTask(), period, delay);
} catch (Exception e) {
return false;
}
}
}
class B {
public boolean execute() {
try {
Timer t = new Timer();
t.schedule (new BTimerTask(), period, delay);
} catch (Exception e) {
return false;
}
}
}
我是否应该用 ScheduledExecutorService 替换 A 类和 B 类中的 Timer 实例,并将 ATimerTask 和 BTimerTask 类设置为 Runnable 类,例如
class B {
public boolean execute() {
try {
final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
scheduler.scheduleWithFixedDelay (new BRunnnableTask(), period, delay);
} catch (Exception e) {
return false;
}
}
}
它是否正确。
编辑:移植的主要动机之一是因为 TimerTask 中引发的运行时异常会杀死该线程并且无法进一步调度它。我想避免这种情况,这样即使我有运行时异常,线程也应该继续执行而不是停止。
注意:你这样做的方式会泄漏线程!
如果你的班级B
将被保留在周围并且每个实例最终将被关闭或关闭或释放,我会这样做:
class B {
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public boolean execute() {
try {
scheduler.scheduleWithFixedDelay(new BRunnnableTask(), period, delay);
return true;
} catch (Exception e) {
return false;
}
}
public void close() {
scheduler.shutdownNow();
}
}
如果您不会对每个实例进行这种清理,那么我会这样做:
class B {
static final ScheduledExecutorService SCHEDULER = Executors.newCachedThreadPool();
public boolean execute() {
try {
SCHEDULER.scheduleWithFixedDelay(new BRunnnableTask(), period, delay);
return true;
} catch (Exception e) {
return false;
}
}
}
Each ExecutorService
您在代码中分配分配一个Thread
。如果你为你的类创建了很多实例B
那么每个实例都会被分配一个Thread
。如果这些不能快速收集垃圾,那么您最终可能会分配数千个线程(但没有使用,只是分配),并且您可能会崩溃整个服务器,使机器上的每个进程都处于饥饿状态,而不仅仅是您自己的 JVM。我已经在 Windows 上看到过这种情况,并且我希望它也可以在其他操作系统上发生。
当您不打算在单个对象实例上使用生命周期方法时,静态缓存线程池通常是一个安全的解决方案,因为您只会保留实际数量的线程running而不是针对您创建的尚未进行垃圾收集的每个实例。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)