#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
Думаю в книге не написано что должно быть строго в таком порядке. Порядок выполнения потоков не гарантируется, эти три фразы могут быть выведены в любом порядке.
Комментариев нет:
Отправить комментарий