#java #multithreading #java-8 #concurrency #java-threads
#java #многопоточность #java-8 #параллелизм #java-потоки
Вопрос:
Я наткнулся на код для последовательной печати чисел с использованием двух потоков в Java. Вот код
public class ThreadPrint {
public static boolean isOdd = false;
public static void main(String[] args) throws InterruptedException {
Runnable even = () -> {
for (int i = 0; i <= 10;)
if (!isOdd) {
System.out.println("Even thread = " i);
i = i 2;
isOdd = !isOdd;
}
};
Runnable odd = () -> {
for (int i = 1; i <= 10;)
if (isOdd) {
System.out.println("odd thread = " i);
i = i 2;
isOdd = !isOdd;
}
};
Thread e = new Thread(even);
Thread o = new Thread(odd);
e.start();
o.start();
}
}
Мой вопрос здесь в том, увеличиваю ли я i как i = 2 в самом цикле, например
for(int i=0; i<10; i =2)
Я получаю вывод в виде четного потока = 0, а затем программа останавливает выполнение. Как этот поток и лямбда-выражение выполняют эту работу в более раннем стиле цикла for, где увеличение находится внутри условия, но почему не в самой строке объявления цикла?
Комментарии:
1. Это называется условием гонки: попробуйте увеличить от
10
до100000
.2. @MAnouti даже если я доведу его до 10000, он будет работать нормально. Почему это ведет себя по-разному, когда я увеличиваю разными способами (один в строке объявления цикла, а другой в условии в цикле)
Ответ №1:
for (int i = 0; i <= 10;)
не увеличивает переменную i
, следовательно, действует как бесконечный цикл. Ваш код не потокобезопасен, нет синхронизации при доступе к isOdd
между двумя потоками. Однако, поскольку цикл бесконечен, каждый поток в конечном итоге передаст if(isOdd)
или if(!isOdd)
пять раз и напечатает значения.
Когда приращение помещается в for
цикл, большинство if
проверок завершатся неудачей, поскольку потоки не синхронизированы, в то время как для каждого потока всего пять попыток.