2011-12-20 13 views
11

スレッドごとにテーブルからデータを読み込み、スレッド&を実行して特定の処理を実行する必要があります。ワーカースレッドin Java

スレッドを開始するだけでいいですか?&タスクが完了したら、1分間スリープモードにしてください。そして、再度テーブルにデータがあるかどうかを確認して、もう一度タスクを実行してください。& 1分寝る...

これは正しいアプローチですか? Javaで同じコードを実行するためのサンプルコードを提供することはできますか?

ありがとうございます!

答えて

20

scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);はように、多くの場合、java.util.concurrentパッケージからJava 5の機能拡張は、ここに大きな助けです。

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(); 

更新:

あなたはすべての単純同じスレッドプールを共有するさまざまな間隔の多くの繰り返しタスクを追加することができているエグゼキュータを使用する利点が、制御シャットダウン。

+1

+1: 'newScheduledThreadPool(1)' = 'newSingleThreadScheduledExecutor()'と 'executor.shutdown()'はすべてのアクティブなタスクをキャンセルします。 –

+1

Executorを使用する利点は、すべて同じスレッドを共有するさまざまな間隔の繰り返しタスクを多数追加できることです。 (そして単純なシャットダウン) –

+0

@PeterLawrey:そうです。私は答えに取り入れました。 – dmeister

0

あなたのアプローチは良いです。あなたのアプローチを進めることができます。

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()); 
} 
} 
+0

をチェックすることもできますこの問題の解決策。 – dendini

1

自分が Executors.newScheduledThreadPool(1)は1 とscheduleAtFixedRateが署名を持っているサイズのthredプールを作成ExcecutorServiceを、使用することですスレッドを作成するための代替:

このサンプルでは、​​あなたのタスクを実行するのに役立ちます:

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); 
    } 
} 
0

あなたはそれとしての目的を待つSLEEPを使用しないでください(エグゼキュータを使用したいFremeworkいけない)伝統的なスレッドに行きたいしたい場合でも 「私はただ、スレッド&を1分間スリープモードに入れて起動すべき」ロックとそのロックを解除しません。ここで待機(タイムアウト)してください。

間違ったアプローチ -

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 
    } 
} 

誰かがjava.util.concurrentパッケージからJava 5の機能拡張が良く含んで示唆したように、あなたは、リンクhttps://www.securecoding.cert.org/confluence/display/java/LCK09-J.+Do+not+perform+operations+that+can+block+while+holding+a+lock