Запуск Java-потока через определенные промежутки времени
-
06-07-2019 - |
Вопрос
У меня есть поток, который необходимо выполнять каждые 10 секунд.Этот поток содержит несколько обращений (12–15) к базе данных на другом сервере.Кроме того, он также имеет доступ примерно к 3 файлам.Следовательно, будет довольно много накладных расходов на ввод-вывод и сеть.
Какова наилучшая стратегия для выполнения вышеперечисленного?
Одним из способов было бы использовать метод сна вместе с циклом while, но это было бы плохим решением.
Будет ли в этом случае полезен класс, похожий на Timer?Кроме того, не лучше ли создать еще пару потоков (один для ввода-вывода и один для JDBC) вместо того, чтобы запускать их в одном потоке?
Решение
Я обнаружил, что ScheduledExecutorService Это отличный способ сделать это. Возможно, он немного сложнее, чем Timer
, но дает большую гибкость при обмене (например, вы можете выбрать использование одного потока или пула потоков; для этого требуются единицы измерения, отличные от миллисекунд).
ScheduledExecutorService executor =
Executors.newSingleThreadScheduledExecutor();
Runnable periodicTask = new Runnable() {
public void run() {
// Invoke method(s) to do the work
doPeriodicWork();
}
};
executor.scheduleAtFixedRate(periodicTask, 0, 10, TimeUnit.SECONDS);
Другие советы
Посмотрите на таймер и TimerTask классы. Они именно то, что вы хотите.
Вы можете создать реализацию TimerTask, которая принимает ваш объект потока в конструктор.
Затем метод run вызовет метод run для потоков.
// Perhaps something like this
Timer t = new Timer();
t.scheduleAtFixedRate(yourTimerTask, 0, 10 * 1000);
// Hopefully your task takes less than 12 seconds
Один из вариантов — создать ScheduledExecutorService, для которого вы затем сможете запланировать свое задание:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
ex.scheduleWithFixedDelay(...);
Если вы решили использовать несколько потоков, вы можете создать ScheduledExecutorService с большим количеством потоков (опять же, через класс Executors).
Что касается количества потоков и того, что вы помещаете в каждый поток, с точки зрения производительности, я бы сказал, что это зависит от:
- для вашего конкретного приложения может ли один поток действительно «работать», пока другой ожидает ввода-вывода?
- будут ли ваши несколько потоков в конечном итоге «избивать один и тот же ресурс» (например,читать файлы из разных мест на одном диске) и, таким образом, замедлять друг друга, или они будут одновременно задействовать разные ресурсы?