Рабочая тема в Java
Мне нужно каждую минуту читать данные из таблицы через поток, а затем выполнять определенные действия.
Должен ли я просто начать поток и поместить его в спящий режим в течение 1 минуты, как только задача будет выполнена. И еще раз проверьте, есть ли в таблице какие-либо данные, выполните задачу снова и перейдите в режим сна в течение 1 минуты...
Это правильный подход? Может ли кто-нибудь предоставить мне пример кода на Java для выполнения того же?
Спасибо!
Ответы
Ответ 1
Как часто, расширения Java 5 из пакета java.util.concurrent представляют собой огромную помощь.
Вы должны использовать ScheduledThreadPoolExecutor. Вот небольшой пример (untestet):
class ToSomethingRunnable implements Runnable {
void run() {
// Add your customized code here to update the contents in the database.
}
}
ScheduledThreadPoolExecutor executor = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> future = executor.scheduleAtFixedRate(new ToSomethingRunnable(),
0, 1, TimeUnit.MINUTES);
// at some point at the end
future.cancel();
executor.shutdown();
Update:
Преимущество использования Executor заключается в том, что вы можете добавить много повторяющихся задач разных интервалов, которые используют один и тот же threadpool - простое, но контролируемое выключение.
Ответ 2
Альтернативой самому создавать поток является использование ExcecutorService, где
Executors.newScheduledThreadPool( 1 )
создает пул размером 1
и scheduleAtFixedRate
имеет подпись: scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
public class ScheduledDBPoll
{
public static void main( String[] args )
{
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool( 1 );
ScheduledFuture<?> sf = scheduler.scheduleAtFixedRate(
new Runnable() {
public void run() {
pollDB();
}
},
1, 60,TimeUnit.SECONDS );
}
}
Ответ 3
Ваш подход хорош. Вы можете продолжить свой подход.
Этот пример поможет вам выполнить свою задачу:
class SimpleThread extends Thread {
public SimpleThread(String str) {
super(str);
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
// Add your customized code here to update the contents in the database.
sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
}
}
Ответ 4
"Должен ли я просто начать поток и поместить его в спящий режим в течение 1 минуты"
Даже если вы хотите, чтобы вы хотели пойти с традиционным потоком (не хотите использовать функцию Fremework), НЕ ИСПОЛЬЗУЙТЕ SLEEP для ожидания цели, так как он не освободит блокировку и ее операцию блокировки. Нажмите здесь, подождите (время ожидания).
Неправильный подход -
public synchronized void doSomething(long time) throws InterruptedException {
// ...
Thread.sleep(time);
}
Правильный подход
public synchronized void doSomething(long timeout) throws InterruptedException {
// ...
while (<condition does not hold>) {
wait(timeout); // Immediately releases the current monitor
}
}
вы можете проверить ссылку https://www.securecoding.cert.org/confluence/display/java/LCK09-J.+Do+not+perform+operations+that+can+block+while+holding+a+lock