2012-02-23 20 views
0

私はスレッドが初めてで、スレッドを実行するクラスがあります。そのスレッドクラスには変数 "errors"があり、その終了時に設定されます。その後、私はメインスレッドでその変数にアクセスする必要があります。どのようにしてそれを可能にするか。これで私を助けてください。以下は私のスニペットです。あるスレッドから他のスレッドへの値の取得

public class ThreadSample { 
    public static void main(String args[]) { 
     new ThreadSample().threadExample(); 
       // Need to access errors variable here 
    } 

    public void threadExample() { 
     MyThread m1 = new MyThread(); 
    } 
} 

class MyThread extends Thread { 
    String errors ; 
    MyThread() {    
     start(); 
    } 
    public void run() { 
     // my code goes here 
    } 
} 

ありがとうございます。

+1

'errors'変数を' volatile'にすると、スレッドと 'join()'した後に 'm1.errors'としてアクセスできるはずです。 – Gray

+0

ありがとうグレー。私はそれを受け入れることができるように、回答のセクションにこれを投稿してください。どうもありがとう。 – i2ijeya

答えて

2

編集:

それが終了するのを待っている)その後、あなただけの、その後のエラーにアクセスすることができ、メインスレッドのメモリはJava thread APIで同期されます。

public String threadExample() { 
    MyThread m1 = new MyThread(); 
    // I would not start in the thread constructor 
    m1.start(); 
    m1.join(); 
    return m1.errors; 
} 

あなたはスレッドがまだ実行されている間、変数のエラーにアクセスしたい場合は、あなたが持っていますいくつかのオプション。あなたは、変更がすべてのスレッドで見られることを意味している変数volatileをマークすることができます周りのオブジェクトを渡す

volatile String errors; 

他の方法を疑問にオブジェクトを設定し、取得するためにAtomicReferenceを使用するかを確認するために​​キーワードを使用することですバックグラウンドスレッドのエラー値がメインスレッドと同期することを確認します。 @ claesvの答えには良い例があります。

+2

AFAIK 'join'はメモリフェンスを導入していますので、ここでは' volatile'が必要なのか分かりません。 – Tudor

+0

Hrm。興味深い点。私はこれについてJavaスレッドAPIで何の言葉も見つけられません。あなたは@ Tudorできますか? – Gray

+0

私はjavadocでも見つけられませんが、Doug Leaのこの記事:http://g.oswego.edu/dl/jmm/cookbook.htmlは最後のMiscellanyセクションでこれを述べています。引用: '逆に、Thread.join()は呼び出し側が終了スレッドによってすべてのストアを見ることを保証する障壁が必要です。これらは通常、これらのコンストラクトの実装に伴う同期によって生成されます。 – Tudor

1

他のクラスから(直接的または間接的に)プロパティを読み取る方法を知っているので、ここではマルチスレッドの問題を対象にします。

まず、異なるスレッドからフィールドにアクセスするとき、あなたは一般的に、すべてのスレッドが同じ状態を見ることを確認するためのアクセスを同期する:

public void run() { 
    longOperation(); 
    synchronized (this) { 
     errors = "some message"; 
    } 
} 

その後もエラーフィールドを読み取るためのMyThreadにメソッドを追加:

public String getErrors() { 
    synchronized (this) { 
     return errors; 
    } 
} 

次に、あなたのメインクラスでは、あなたがしたいだけ:

MyThread m1 = new MyThread(); 
doSomeStuffWhileWaitingForLongOperation(); 
m1.join(); // wait for operation to finish before reading errors 
String errors = m1.getErrors(); 
doSomethingWith(errors); 
+0

あなたのお返事ありがとうございますclaesv。これもうまく動作します。 – i2ijeya

+1

すべての 'synchronized'ブロックは必要ないと思います。誰もワーカースレッド以外の 'errors'変数にアクセスしていません。メインスレッドは、作業者が終了した後にのみ値を取得します。さらに、参照割り当てはアトミックです。 – Tudor

+0

@ Tudor、そうです。私は参加がメモリフェンスを導入していることを知らなかったので、フィールドへのアクセスを同期するという私のコメント。 – claesv

関連する問題