1

threadAthreadBの 2 つのスレッドを考えてみましょう。(たとえば、threadAを UI スレッドとし、threadBを の独自のサブクラスとしThreadます。)データの可視性に関して、クラスをthreadAでインスタンス化し、それをthreadBのコンストラクターに渡し、それをthreadBから排他的に使用することは安全ですか? これをコードで明確にしましょう。(コードは単純化されているため、このアーキテクチャは実際のアプリケーションでは実際の形式で意味があることに注意してください。)

public class SomeClass {
    public SomeClass(....) {
       // initialization
    }
}

public class MyCustomThread extends Thread {
    public MyCustomThread(SomeClass someClass) {
        mSomeClass = someClass;
    }

    @Override
    public void run() {
           // operate on mSomeClass         
    }
}

そして、すべてを起動する方法は次のとおりです(場所は関係ありません)。これはthreadAによって呼び出されます。

public void launchThread() {
   SomeClass someClass = new SomeClass();
   MyCustomThread threadB = new MyCustomThread(someClass); // MyCustomThread is a subclass of Thread
   threadB.start();
   // After this point, threadA never accesses someClass,
   // and only threadB is operating on it
}

コンストラクターを同期することは許可されておらず、その中に同期されたコードは必要ないことを私は知っています (クラスがその作成者スレッドで構築されるまで、this参照は、リークされない限り、他のスレッドで使用できないため)。したがって、私の質問はデータの可視性に関するものです: が呼び出された後にthreadAsomeClassから (およびその参照データに)アクセスしない限り、コードは安全ですか?threadB.start()

つまり、threadB.run()最新バージョンのsomeClassデータ (フィールド、内部参照など) が表示されますか? 私の推測: threadBが初めてアクセスしたsomeClass後には外部からの変更はないため、 threadBは beforeからキャッシュされたコピーを持つことができないため、正しい値を確認する必要があります。したがって、上記の理由により、からの同期ブロックでアクセスする必要はありません。(繰り返しますが、 threadBの開始後にthreadAがアクセスしないことが保証されていることに注意してください。)someClasssomeClassthreadB.run()someClass

4

1 に答える 1

2

あなたが言っている場合threadB.start()、 によって参照されるインスタンスはsomeClass、他のスレッドによって変更されなくなります: はい、threadB.run()最新バージョンが表示されます。

このシナリオで発生する可能性のある同時実行/競合状態は実際にはありません。すべてが順番に起こっています。単にThreads であるオブジェクトを持っているだけで、少し偏執症になる可能性があると思います:)。

于 2012-07-04T00:42:29.463 に答える