#java #synchronized
Постигаю основы Java по книге Герберта Шилдта Java 8 Полное руководство. Решил воспроизвести пример с книги: public class Test { public static void main(String args[]) { Callme target = new Callme(); Caller obj1 = new Caller(target, "Welcome"); Caller obj2 = new Caller(target, "to synchronized"); Caller obj3 = new Caller(target, "world!"); try { obj1.t.join(); obj2.t.join(); obj3.t.join(); } catch(InterruptedException e) { System.out.println("interrupted!"); } } } class Callme { void call(String msg) { System.out.print("[" + msg); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Thread is interrupted!"); } System.out.println("]"); } } class Caller implements Runnable{ String msg; Callme target; Thread t; public Caller(Callme trg, String s) { target = trg; msg = s; t = new Thread(this); t.start(); } public void run() { synchronized(target) { target.call(msg); } } } Судя по учебнику вывод должен быть таким: [Welcome] [to synchronized] [world!] Вместо этого получаем следующее: [Welcome] [world!] [to synchronized] Заранее прошу прощения за, возможно, нубский вопрос, но ошибку в упор не вижу. UPD: Даже если поставить задержку между созданием объектов следующим образом: Callme target = new Callme(); Caller obj1 = new Caller(target, "Welcome"); Caller obj2 = new Caller(target, "to synchronized"); Thread.sleep(700); Caller obj3 = new Caller(target, "world!"); то все равно не удается добиться желаемого эффекта. Как по мне так очень странно.
Ответы
Ответ 1
Смысл примера в следующем. На каждый возов идет две операции печати. При синхронизации гарантируется, что метод выполнит обе печати, прежде чем другой поток сможет печатать что-либо свое. Без синхронизации будет что-то типа [Welcome[to synchronized[world!] ] ] Порядок же выполнения потоков не детерминирован. Кто быстрее зайдет в критическую секцию, тот и будет печатать, остальные будут ждать окончания.Ответ 2
Все верно, порядок здесь не гаратируется. Планировщик может приостановить любой из потоков до блока synchronized и дать процессорное время другому потоку, не зависимо от того когда он был создан. Синхронизация в данном случае обеспечивает лишь, выполнение метода call одним потоком в один момент времени.Ответ 3
Думаю в книге не написано что должно быть строго в таком порядке. Порядок выполнения потоков не гарантируется, эти три фразы могут быть выведены в любом порядке.
Комментариев нет:
Отправить комментарий