Я пытаюсь изучить параллелизм в Java, но что бы я ни делал, 2 потока выполняются последовательно, а не параллельно, поэтому я не могу воспроизвести распространенные проблемы параллелизма, описанные в руководствах (например, помехи потоков и ошибки согласованности памяти). Пример кода:
public class Synchronization {
static int v;
public static void main(String[] args) {
Runnable r0 = () -> {
for (int i = 0; i < 10; i++) {
Synchronization.v++;
System.out.println(v);
}
};
Runnable r1 = () -> {
for (int i = 0; i < 10; i++) {
Synchronization.v--;
System.out.println(v);
}
};
Thread t0 = new Thread(r0);
Thread t1 = new Thread(r1);
t0.start();
t1.start();
}
}
Это всегда дает мне результат, начиная с 1 и заканчивая 0 ( независимо от длины цикла ). Например, код выше дает мне каждый раз:
1
2
3
4
5
6
7
8
9
10
9
8
7
6
5
4
3
2
1
0
Иногда второй поток запускается первым, и результаты такие же, но отрицательные, поэтому он все еще работает в последовательном режиме.
Пробовал в Intellij и Eclipse с одинаковыми результатами. Процессор имеет 2 ядра, если это имеет значение.
ОБНОВЛЕНИЕ: оно наконец стало воспроизводимым с огромными циклами (начиная с 1_000_000), но все же не каждый раз и только с небольшим количеством окончательного расхождения. Также кажется, что выполнение операций в циклах «тяжелее», например, печать имени потока делает его более воспроизводимым. Ручное добавление sleep в thread также работает, но, так сказать, делает эксперимент менее чище. Кажется, причина не в том, что первый цикл завершается до запуска второго, потому что я вижу, как оба цикла печатаются в консоль, продолжая работать, и все еще дают мне 0 в конце. Причины, похоже, больше похожи на гонку потоков по одной и той же переменной. Я углублюсь в это, спасибо.