У нас есть связующий компонент между устаревшим кодом и текущим кодом.По сути, все унаследованное приложение является однопоточным и имеет ужасные проблемы, когда обновление пользовательского интерфейса для одной инструкции может происходить от 5 до 8 раз.
Я хочу опубликовать асинхронное сообщение после того, как первый запрос на обновление произойдет +2 секунды.
Давайте не будем зацикливаться на том, почему, это не то, что я действительно хочу сделать, но у меня естьчтобы понять, как по крайней мере сделать это, чтобы я мог реализовать реальное решение.
Runnable task = () -> {
try {
TimeUnit.SECONDS.sleep(2);
messageBus.publishAsynch(new LegacyUiUpdateEvent());
} catch (InterruptedException e) {
// TODO Log something
Thread.currentThread().interrupt();
}
};
@Override
public void update(Observable arg0, Object arg1) {
ExecutorService executor = Executors.newSingleThreadExecutor();
if (futureTask == null || futureTask.isDone()) {
futureTask = executor.submit(task);
try {
executor.awaitTermination(10, TimeUnit.SECONDS);
executor.shutdownNow();
} catch (InterruptedException e) {
// TODO Log something
Thread.currentThread().interrupt();
}
}
}
Теория: Если будущая задача не существует, мы создаем ее, как только она там, если это не сделано (потому что это ложное устаревшее обновление 4 / x, где x ∈ [5,12] и спящий режим все еще действует), то мы полностью пропускаем и не создаем нового исполнителя.
Проблема в том, что , насколько я могу судить, executor.submit(task)
на самом деле не происходит на новом протекторе.Как я уже говорил, унаследованное приложение является однопоточным, и после того, как я увеличил сон до 15 секунд, было совершенно очевидно, что оно отправляет весь текущий поток в спящий режим.
Как бы я поместил свои такты в совершенно новый поток(используя библиотеку concurrency
) и избегая выполнения задачи несколько раз, даже если метод обновления вызывается слишком часто (и это на 100% вне моего контроля).Я думаю, что future.isDone()
вещь работает, но не 100%