threadAとthreadBの 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がアクセスしないことが保証されていることに注意してください。)someClass
someClass
threadB.run()
someClass