Рабочая тема в 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