С the tutorial Я читаю:Синхронизация Сбой в Java
это не возможно для двух вызовов синхронизированных методов на же объект чередовать. Когда один поток выполняет синхронизированный метод для объекта, все остальные потоки, которые вызывают синхронизированные методы для одного и того же объекта (приостановить выполнение) до тех пор, пока не будет выполнен первый поток с объектом.
Однако в моем простом примере все еще существует гоночное соревнование для доступа к объекту 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
Это означает, что один из потоков не удалось изменить объект. Может кто-нибудь объяснить мне, почему это происходит и предложить решение проблемы?