#java #multithreading
Вопрос:
Я использую конструктор потоков для создания потоков. Я ожидал, что приведенный ниже код будет выполняться 3 отдельными потоками и разными выходами. Может ли кто-нибудь, пожалуйста, объяснить, почему вывод отличается от моего понимания(почему поток 2 используется для вызова m1 дважды, а не t3)?
Код:-
public static void main( String[] args ) {
new SynchronizedExample().execute();
}
void execute() {
SynchronizedExample s1 = new SynchronizedExample();
Thread t1 = new Thread(s1::m1);
Thread t2 = new Thread(s1::m1);
Thread t3 = new Thread(s1::m2);
t1.start();
t2.start();
t3.start();
}
public synchronized void m1(){
try {
System.out.println("Current Thread - " Thread.currentThread().getName());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("M1");
}
public void m2() {
System.out.println("M2");
}
}
Выход:-
Current Thread - Thread-0
M2
M1
Current Thread - Thread-1
M1
Ожидаемый Результат:-
Current Thread - Thread-0
M2
Current Thread - Thread-1
M1
Current Thread - Thread-2
M1
Комментарии:
1.
m2
не распечатывает текущее имя потока. Таким образом, результат будет именно таким, как вы ожидали. Нить 0 подобранаm1
, иCurrent Thread - Thread-0
затем печатаетсяM1
. Пока это происходит, поток 2 поднялсяm2
и просто печатаетm2
. Поток 1 подобрал другогоm1
(в какой-то момент, не могу сказать), но не может начать, потому что методsynchronized
, поэтому печатаетCurrent Thread - Thread-1
, а затемM1
, как только Поток 0 уронил монитор.2. У вас нет a
System.out.println("Current Thread - " Thread.currentThread().getName());
в m2, и m2 не синхронизирован.3. Кстати, выходные данные из потоковых вызовов
System.out.println
не всегда отображаются на консоли в хронологическом порядке. Всегда включайте метку времени, например,Instant.now()
для изучения, если вы хотите увидеть истинную последовательность. Или используйте потокобезопасную коллекцию для выходных строк, а неSystem.out
.
Ответ №1:
Ты все запутал.
Я прокомментирую ваш вывод:
Current Thread - Thread-0 [t1 - m1] M2 [t3 - m2] M1 [t1 - m1] Current Thread - Thread-1 [t2 - m1] M1 [t2 - m1]
Ваш код что-то печатает, затем ждет, затем печатает еще. Таким образом, один метод получает свои строки System.out, размазанные по первой и третьей строке. Ваш метод m2 вообще не печатается Current Thread - ...
, так что то, чего вы ожидаете, очевидно, не может произойти. Добавьте отпечаток.
Комментарии:
1. Спасибо! с моей стороны это был отличный обзор.