ПРИМЕЧАНИЕ. То, как вы это сделали, приведет к утечке потоков!
Если ваш класс 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;
}
}
}
Каждый ExecutorService
, который вы выделяете в своем коде, выделяет один Thread
. Если вы создадите много экземпляров вашего класса B
, то каждому экземпляру будет присвоено Thread
. Если они не будут быстро собирать мусор, то вы можете получить много тысяч выделенных потоков (но не использованных, просто выделенных), и вы можете привести к сбою на всем сервере, что приведет к истощению всех процессов на компьютере, а не только вашей собственной JVM. Я видел, что это происходит в Windows, и я ожидаю, что это может произойти и в других ОС.
Статический пул потоков в кэше очень часто является безопасным решением, когда вы не намерены использовать методы жизненного цикла в отдельных экземплярах объекта, поскольку вы сохраняете столько потоков, сколько фактически выполняется и не один для каждого создаваемого вами экземпляра, который еще не собран мусором.