Страницы

Поиск по вопросам

четверг, 19 декабря 2019 г.

Java оператор synchronized

#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



Думаю в книге не написано что должно быть строго в таком порядке. Порядок выполнения потоков не гарантируется, эти три фразы могут быть выведены в любом порядке.

Комментариев нет:

Отправить комментарий