Я знаю, що такі складні операції, як, наприклад 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
ніколи не розбивають один одного ). Тест на перегони потребує більш жорсткої внутрішньої петлі. Надрукуйте резюме в кінці (як це робив хтось нижче з одиничною тестовою рамкою).