2011-01-06 3 views
1

を使用する必要があり、私は別のスレッドを作ってるんだ:スレッドコード...これに何か、私はアプリケーションサーバーの起動時に自動的に発射サーブレットを持っており、その初期化中に()は、Java 1.4

init(){ new FooThread().start() } 
FooThread()内の

、私は定期的にDBの値のステータスをチェックし、値に応じてWebサービスコールを行いたいと思います。これらの2つのタスクが完了すると、スレッドをスリープして一定の期間待ってから繰り返します。 このサイクルはちょうど永遠に続くでしょう。

FooThread:それは競合状態と不定動作につながる可能性があるため、

public class FooThread implements Runnable{ 
    Thread t; 

    FooThread(){ 
    t = new Thread(this, "FooThread"); 
    } 

public void start(){ 
    t.start(); 
} 

    public void run() { 
    try{ 
     while(true){ 
     //do the db check, then conditionally do the web services call 
     logger.info("*** calling sleep() ***"); 
     Thread.sleep(50000); 
     logger.info("*** now awake ***"); 
     } 
    } catch (InterruptedException e) { 
     System.out.println("*** FooThread interrupted"); 
    } 
    } 
} 
+5

申し訳ありませんが、あなたの質問は何ですか? –

+4

ここに質問はないので、投票に参加しました。 「自分のコードを確認する」は、少なくともあなたが探している特定の基準がなければ、一般的には受け入れられません。 –

+0

@Petro Semeniuk:質問はタイトルにあります。 :) –

答えて

6

あなたのコンストラクタ内のスレッドを起動しないでください。代わりに、オブジェクトを作成した後にstart()メソッドを呼び出します。

EDIT: コンストラクタが完了する前に、あなたはthisポインタを公開する可能性があるので、それは悪いです

理由があります。

+1

あなたはもっと喜んで説明することができます、どのような不確定な行動が起こる可能性がありますか? –

+0

私はスレッドを拡張したくないのですが、Runnableを実装したいのですが、私がやったことをする以外に選択肢はありません。 – bmw0128

+0

本当ではありません。スレッドを開始するコードをrunメソッドの先頭に移動できます。 –

0

Threadからサブクラス化する場合は、tFooThreadに新しく作成する必要はありません。 FooThreadのインスタンスは、すでにスレッドです。コンストラクタでstart()を呼び出す必要はありません。

init()内部FooThreadの適切な使用は、次のようになります。あなたがFooThreadのコンストラクタの上にラインアウトコードで

FooThread ft = new FooThread(); 
ft.start();       // calls run() inside FooThread 

run()は正常に見える、任意のロジックを必要としません。

+0

'FooThread'は名前にもかかわらず、' Runnable'の実装です。 'Thread'のサブクラスです。 –

+0

@マークピーターズ:ああ、私はその部分を見落とした。ありがとう:)私はThread_partからサブクラスを追加しました。 – sjngm

+1

'Thread'を拡張するのは、とにかく悪いフォームです。それはその作品の実行環境にその作品を不必要に結びつけます。 IMOでは 'Thread ft = new Thread(new FooThread());を実行する方が良いです。 ft.start() ' –

2

あなたがやっていることは安全でないとみなされます。この参照がコンストラクタをエスケープすると、部分的に構築されたオブジェクトをスレッドクラスに送ることができます。あなたのクラスとrunメソッドは、このように見えた場合はどのようなあなたの例では

public class FooThread implements Runnable{ 
    Thread t; 

    private int someInt; 
    private Object someObject; 

    FooThread(){ 
    t = new Thread(this, "BBSThread"); 
    t.start(); 
    someInt = 10; 
    someObject = new Object(); 
    } 

    public void run() { 
    System.out.println(this.someInt); 
    System.out.println(this.someObject);  
    } 
} 

それはsomeIntは0を出力し、SomeObjectのがnull印刷していることが可能です。あなたのオブジェクトは技術的に構築されていますが、完成していません。

+0

ありがとうございますsomeIntとsomeObjectの初期化がコンストラクタの最初の行だった場合、この懸念は消えますか? – bmw0128

+0

はいそうです。スレッドの開始前に発生したフィールドへのすべての書き込みは、そのスレッドから見えます。しかし、あるクラスがFooThreadを拡張してrunメソッドを上書きしたとします。そのサブクラスには、そのコンストラクタで作成される他のフィールドがあります。サブクラスがそのコンストラクタのフィールドを割り当てられる前にスレッドが開始されたため、子クラスが部分的に構築されました –

+0

私は説明していると思います。私はこの特定のケースでは何もしていないので、私はその懸念がない、そうですか? – bmw0128

関連する問題