Я знаю, що такі складні операції, як, наприклад i++, не є безпечними для потоків, оскільки вони включають кілька операцій.
Але чи перевірка посилання на себе є потоком безпечної роботи?
a != a //is this thread-safe
Я спробував це запрограмувати і використовувати кілька потоків, але це не вийшло з ладу. Я думаю, я не міг імітувати гонку на своїй машині.
Редагувати:
public class TestThreadSafety {
private Object a = new Object();
public static void main(String[] args) {
final TestThreadSafety instance = new TestThreadSafety();
Thread testingReferenceThread = new Thread(new Runnable() {
@Override
public void run() {
long countOfIterations = 0L;
while(true){
boolean flag = instance.a != instance.a;
if(flag)
System.out.println(countOfIterations + ":" + flag);
countOfIterations++;
}
}
});
Thread updatingReferenceThread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
instance.a = new Object();
}
}
});
testingReferenceThread.start();
updatingReferenceThread.start();
}
}
Це програма, яку я використовую для перевірки безпеки потоку.
Дивна поведінка
Оскільки моя програма починається між деякими ітераціями, я отримую значення вихідного прапора, а це означає, що !=перевірка посилання не вдається на одній посиланні. АЛЕ після деяких ітерацій вихід стає постійним значенням, falseа потім виконання програми протягом тривалого часу не генерує єдиного trueвиходу.
Як показує вихід після деяких n (нефіксованих) ітерацій, вихід здається постійним значенням і не змінюється.
Вихід:
Для деяких ітерацій:
1494:true
1495:true
1496:true
19970:true
19972:true
19974:true
//after this there is not a single instance when the condition becomes true
1234:trueніколи не розбивають один одного ). Тест на перегони потребує більш жорсткої внутрішньої петлі. Надрукуйте резюме в кінці (як це робив хтось нижче з одиничною тестовою рамкою).