Я новичок в Java. У меня возникла проблема при обучении Java многопоточному программированию, и вот код:
public class TestMultiThreads {
private static int i = 100;
private static Runnable r = () -> {
while (i > 0) {
i--;
System.out.println(i);
}
};
public static void main(String[] args) {
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
}
}
И результат здесь: (не все то же самое, но почти такое)
99
97
96
...
2
1
0
98
Из того, что я узнал, я знаю, что 2 потока вытесняют срезы времени процессора. Однако в этом случае я не могу найти ни одной ситуации, которая могла бы соответствовать выходу.
Обновление
Всем спасибо! С вашей помощью я только что преобразовал файл .class в байт-код Java, и я думаю, что у меня есть предположение. (или ближе к истине)
это часть байт-кода, run()
метод в Runnable r
public void run();
Code:
0: invokestatic #2 // Method top/littlefogcat/concurrent/TestMultiThreads.access$000:()I
3: ifle 22
6: invokestatic #3 // Method top/littlefogcat/concurrent/TestMultiThreads.access$010:()I
9: pop
10: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
13: invokestatic #2 // Method top/littlefogcat/concurrent/TestMultiThreads.access$000:()I
16: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
19: goto 0
22: return
Я не очень понимаю Java байт-код, но могу прочитать некоторые.
Думаю, вот что: возможно, я неправильно понял, как JVM распределяет фрагменты времени ЦП. Я думал, что только когда поток завершает sh выполнение одной строки кода, другой поток имеет возможность вытеснить фрагменты времени ЦП. Возможно это неправильно. Одна строка кода Java может быть преобразована в несколько строк байт-кода. JVM может распределять время ЦП на основе меньшего блока, такого как строка байт-кода или что-то еще. В любом случае, использовать переменную stati c в Java небезопасно. Необходимо использовать synchronized
или другие поточно-ориентированные способы.
И спасибо вам, ребята