4

多くのスレッドから同時に静的変数にアクセスするにはどうすればよいですか。

次のようなクラスがある場合

Class A {
    public static boolean FLG=false;
    .....................
    ....................
}

そして、スレッド1の値にアクセスする必要があります

....................
public void run() {
    boolean t1=A.FLG;
    ..................
}

スレッド2から、次のように値を設定する必要があります

....................
public void run() {
    A.FLG=true;
    ..................
}

これによりメモリ違反が発生しますか? もしそうなら、そのような状況を処理するための推奨される方法は何ですか?.

4

5 に答える 5

3

静的変数を同期メソッドでラップし、好きなようにメソッドを呼び出します

public static synchronized void method1(){
//Whatever
}

public static synchronized void method2(){
//Whatever again
}

メソッドへのアクセスを同期する方法は他にもあることに注意してください。同じメソッドにアクセスするスレッドがビジーな環境では、より効率的であると見なされます。

ReentrantLockクラスを確認してください。同期と RentrantLock をいつ使用するかについての回答と、Google で見つけられるその他の多くの情報もあります。

また、peterの答えとmuelのコメントが示唆するように。変数を揮発性としてマークするbooleanと役立つはずです。volatileブール変数は、その初期値 (または) をキャッシュしません。JVM は時折それを行うことができますが、これはプログラマーにとって予期しないことでした。falsetrue

于 2013-08-28T12:03:17.717 に答える
1

2 つのスレッドが静的変数に異なる値を設定しようとして、実際にどのような値が実​​際に存在するのかがわからないという望ましくない状況が発生する場合があります。最善の方法 (単純なシナリオで考える) AtomicBoolean ( http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html ) を使用していると思います。オブジェクトの値を変更して使用します (オブジェクトを常に使用するのではなく、別のスレッドが値を変更する可能性があり、予期しないシナリオが発生する可能性があります)。

もう 1 つの提案は、Byteman を使用して並行テストを作成することです。

よろしく、ルアン

于 2013-08-28T12:09:41.583 に答える
0

同期された ReentrantLock を使用したくない場合は、独自のロジックを記述できます。

例:

public class A extends Thread{

    public static boolean FLG=false;

    public A(String threadName) {
        start();
        setName(threadName);
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            if(this.getName().equals("getterThread") && FLG == true){
                boolean t1=A.FLG;
            }
            if(this.getName().equals("setterThread") && FLG == false){
                A.FLG = true;
            }
        }

    }

    public static void main(String[] args) {

        A dad = new A("getterThread");
        A son = new A("setterThread");
    }
}
于 2013-08-28T12:39:40.073 に答える