Ваша проблема в том, что вы неправильно поняли цель сервлета . Он намерен действовать по HTTP-запросам, не более того. Вам нужна только фоновая задача, которая выполняется один раз на ежедневной основе.
@Schedule
Если ваша среда поддерживает EJB (например, WildFly, JBoss AS / EAP, TomEE, GlassFish и т. Д.), Тогда используйте @Schedule
.
@Singleton
public class BackgroundJobManager {
@Schedule(hour="0", minute="0", second="0", persistent=false)
public void someDailyJob() {
// Do your job here which should run every start of day.
}
@Schedule(hour="*/1", minute="0", second="0", persistent=false)
public void someHourlyJob() {
// Do your job here which should run every hour of day.
}
@Schedule(hour="*", minute="*/15", second="0", persistent=false)
public void someQuarterlyJob() {
// Do your job here which should run every 15 minute of hour.
}
}
Да, это действительно все. Контейнер автоматически подберет и управляет им.
ScheduledExecutorService
Если ваша среда не поддерживает EJB (то есть не настоящий Java EE-сервер, например Tomcat, Jetty и т. Д.), Используйте ScheduledExecutorService
. Это может быть инициировано ServletContextListener
. Вот пример kickoff:
@WebListener
public class BackgroundJobManager implements ServletContextListener {
private ScheduledExecutorService scheduler;
@Override
public void contextInitialized(ServletContextEvent event) {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
}
@Override
public void contextDestroyed(ServletContextEvent event) {
scheduler.shutdownNow();
}
}
Если классы заданий выглядят следующим образом:
public class SomeDailyJob implements Runnable {
@Override
public void run() {
// Do your daily job here.
}
}
public class SomeHourlyJob implements Runnable {
@Override
public void run() {
// Do your hourly job here.
}
}
public class SomeQuarterlyJob implements Runnable {
@Override
public void run() {
// Do your quarterly job here.
}
}
java.util.Timer
/ java.lang.Thread
в Java EE Никогда не используйте java.util.Timer
и / или java.lang.Thread
в Java EE. Это рецепт неприятностей. Подробное объяснение можно найти в этом ответе JSF по одному и тому же вопросу: Истеризация потоков в управляемом компоненте JSF для запланированных задач с использованием таймера .
Оператор var foo;
объявляет переменную foo
и устанавливает ее значение неопределенным , если оно уже не имеет значения . Ваш foo
имеет значение, поскольку var foo;
на самом деле ничего не делает.
Если вы удалите foo function
и замените его простой переменной, вы увидите то же поведение.
Причина, по которой функция является значением foo
, заключается в том, что в этой строке:
var foo;
Вы просто заявляете foo
- это утверждение, которое ничего не делает.
Если вы на самом деле установите foo
на что-то, например «FooBar»:
function foo() {
console.log(8);
}
var foo = "FooBar";
console.log(foo);
It перезаписывает функцию, потому что, как показано в в этом вопросе , объявление чего-либо со значением var
, которое является значением, приведет к тому, что это значение будет «поднято» наверх и, таким образом, является фактическим значением идентификатора. ,
будет ли объявление переменной перезаписывать объявление функции?
blockquote>Нет. Перед выполнением любого кода среда выполнения находит все объявления функций и переменных и инициализирует с ними новую область видимости. Вещи немного отличаются между оценкой кода скрипта и оценкой области действия функции, но результат один и тот же:
- Дублирующиеся объявления игнорируются.
- Объявление функции оценивается в конце и присваивается их соответствующему имени.
В глобальной области видимости, поскольку
foo
является как именем функции, так и объявлением переменной, объявление переменной игнорируется. А так как у него нет инициализатора, значениеfoo
не изменяется, когда эта строка фактически вычисляется.Подробности можно найти в спецификации языка .
Вопрос 2: я набрал тот же код в онлайн-редакторе https://jsbin.com/dezixozewi/edit?js,console , он выдает ошибку как «идентификатор» 'foo' уже объявлен '. поэтому он вообще не допускает дублирования деклараций.
blockquote>Непонятно, как jsbin оценивает код, но он действителен.
var foo;
просто указывает на ячейку памяти foo
. Бывает, что вы уже объявили функцию там, поэтому значение foo
по-прежнему остается функцией.
Это ничем не отличается от того, что ты сделал:
var x = 2;
var x; // We're not setting a value with `=`, so nothing gets overridden
x; // 2