私が読んだチュートリアルから:
同じオブジェクトで同期されたメソッドの2つの呼び出しがインターリーブすることはできません。1つのスレッドがオブジェクトの同期メソッドを実行している場合、同じオブジェクトブロックの同期メソッドを呼び出す他のすべてのスレッドは、最初のスレッドがオブジェクトで完了するまで実行を一時停止します。
ただし、私の単純な例では、message
オブジェクトにアクセスするためのレース競争がまだあります。
public class TestThread extends Thread{
int thread;
StringBuilder message;
public TestThread(int thread, StringBuilder message) {
this.thread=thread;
this.message=message;
start();
}
public void run() {
synchronized(this){
for (int i=0; i<1000000; i++) {
double a=2*2;
}
modifyMessage();
}
}
public synchronized void modifyMessage() {
message.append(thread);
}
}
public class TestMultithreading {
static TestThread[] testThreads = new TestThread[5];
public static void main(String args[]) {
StringBuilder message = new StringBuilder("A");
for (int i=0;i<5;i++)
testThreads[i] = new TestThread(i, message);
for (int i=0;i<5;i++)
try {
testThreads[i].join();
} catch (InterruptedException e) {}
out.println(message);
}
}
私はこれが長さ6の文字列の保証された出力を持つことを期待しています。しかし、時々私はこのようなものを見ます:
A1034
これは、スレッドの1つがオブジェクトの変更に失敗したことを意味します。誰かが私に説明してもらえますか、なぜこれが起こるのか、そして問題の解決策を提案できますか?
あなたはすでにあなた自身の質問に答えました:
1つのスレッドがオブジェクトの同期メソッドを実行している場合、同じオブジェクトブロックの同期メソッドを呼び出す他のすべてのスレッド
同じオブジェクトのメソッドに対する同期された唯一のブロックアクセス。つまり、すべてのスレッドでmodifyMessage()を同時に呼び出すことができます。
あなたが探しているのはこのようなものです:
for (int i=0; i<1000000; i++) {
double a=2*2;
}
synchronized(message){
modifyMessage();
}
これで、メソッドはStringBuilderインスタンスごとに1回だけ呼び出されます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加