2012-11-27 5 views
8

複数の異なるスレッド間で変数を共有する:私はこのような複数のスレッド間で変数を共有したい

boolean flag = true; 
T1 main = new T1(); 
T2 help = new T2(); 
main.start(); 
help.start(); 

私はこれらは私が「二つの異なるJavaクラスがあり、メインとヘルプスレッド間flagを共有したいです作成されました。これを行う方法はありますか?ありがとう!

答えて

17

T1T2の両方は、この変数を含むクラスを参照できます。この変数をとし、変数にすることができます。これは、その変数への変更が両方のスレッドで即座に見えることを意味します。

詳細については、this articleを参照してください。

揮発性変数は、視認性の同期の機能が、アトミック機能の どれを共有しています。つまり、スレッドは に自動的に揮発性変数の最新の値を表示します。 これらは、スレッドの安全性を提供するために使用できますが、 複数の変数の間、または変数の現在の値と の将来の値の間に制約を課すものではありません。

揮発性とより複雑な状態を共有する手段を使用することの長所/短所に注意してください。

+0

ありがとうございますが、たとえばT1の内部から「フラグ」を参照してください。私はParentClass.flagのようなものを試しましたが(ParentClassは "main"と "help"を開始するクラスです)、それは動作していないようです... – user1031431

+0

T1/T2を含むクラスへの参照をインスタンス化します、フラグをそのクラスのメンバーにしますか? –

4
  1. 静的にするとこの問題を解決できます。
  2. 他のスレッドでメインスレッドへの参照と、変数見える
3

T1のインスタンスとの間で、それを目に見えるようにすることになっていT2あなたは2つのクラスが変数を含むオブジェクトへの参照が含まれて作ることができます。

スレッドが実行されているときに変数を変更する場合は、同期を考慮する必要があります。最適なアプローチは、正確な要件によって異なりますが、主なオプションは以下のとおりです。

  • 変数を作成しますvolatile;
  • AtomicBooleanに変換します。
  • は、それを使用するコードの回りに本格的な同期を使用します。
  • 他の提案に加えて
6

- あなたはまた、コントロールクラスにフラグをラップすることができますし、あなたの親クラスでの最後のインスタンスを作る:

public class Test { 
    class Control { 
    public volatile boolean flag = false; 
    } 
    final Control control = new Control(); 

    class T1 implements Runnable { 
    @Override 
    public void run() { 
     while (!control.flag) { 

     } 
    } 
    } 

    class T2 implements Runnable { 
    @Override 
    public void run() { 
     while (!control.flag) { 

     } 
    } 
    } 

    private void test() { 
    T1 main = new T1(); 
    T2 help = new T2(); 

    new Thread(main).start(); 
    new Thread(help).start(); 
    } 

    public static void main(String[] args) throws InterruptedException { 
    try { 
     Test test = new Test(); 
     test.test(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 
} 
+0

ありがとうございます。 OldCurmufgeon、それは私が探していたものです;) – user1031431

0

あなたはロック変数を使用することができます「」 「b」を同期させ、「クリティカルセクション」を逆の順序でロックする。例えば。 "a"を通知してから "b"をロックし、 "PRINT"、 "b"を通知して "a"をロックします。

コード下記参照してください: -

public class EvenOdd { 

static int a = 0; 

public static void main(String[] args) { 

    EvenOdd eo = new EvenOdd(); 

    A aobj = eo.new A(); 
    B bobj = eo.new B(); 

    aobj.a = Lock.lock1; 
    aobj.b = Lock.lock2; 

    bobj.a = Lock.lock2; 
    bobj.b = Lock.lock1; 

    Thread t1 = new Thread(aobj); 
    Thread t2 = new Thread(bobj); 

    t1.start(); 
    t2.start(); 

} 

static class Lock { 
    final static Object lock1 = new Object(); 
    final static Object lock2 = new Object(); 
} 

class A implements Runnable { 

    Object a; 
    Object b; 

    public void run() { 
     while (EvenOdd.a < 10) { 
      try { 
       System.out.println(++EvenOdd.a + " A "); 
       synchronized (a) { 
        a.notify(); 
       } 
       synchronized (b) { 
        b.wait(); 
       } 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

     } 
    } 
} 

class B implements Runnable { 

    Object a; 
    Object b; 

    public void run() { 
     while (EvenOdd.a < 10) { 

      try { 
       synchronized (b) { 
        b.wait(); 
        System.out.println(++EvenOdd.a + " B "); 
       } 
       synchronized (a) { 
        a.notify(); 
       } 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

     } 
    } 
} 

}

OUTPUT: - 1 2 B 3 4 B 5 6 B 7 8 B 9 A 10 B

関連する問題