Гарантия порядка событий при наличии параллельных вызовов методов

class server {
    private Vector<Msg> v = new ...
    ...
    public void deliver(Msg msg) {
       ...
       v.add(msg);
    }
}

class client {
    private server s = server.getInstance(); // singleton
    ...
    public void propose() {
       s.deliver(new Msg( ... ));
    }
}           

Если несколько одновременных клиентов передают значение (Msg объект) на сервер с помощью [несинхронизированного!] deliver метода, можно ли предположить, что любой клиент, вызывающий [или, точнее, входящий] deliver первым, сохранит свое значение сначала в v или делает deliver синхронизированным обязательным, чтобы это предположение сохранялось?


person fbahr    schedule 15.07.2012    source источник


Ответы (2)


Нет, вы не можете сделать такое предположение, потому что планировщик может прервать текущий поток, который находится внутри deliver(), но еще не добрался до v.add(msg). Планировщик переключается на другой поток, который вызывает deliver() (после), но ему удается завершить весь вызов deliver().

Если вы синхронизируете метод deliver(), это не помешает планировщику тем временем прервать выполнение. Но ни один другой поток не сможет войти в этот метод, пока первый поток удерживает блокировку, т. е. в конечном итоге планировщик разбудит исходный поток и позволит ему закончить.

Кстати, Vector довольно древний, есть и лучше альтернативы.

person Tomasz Nurkiewicz    schedule 15.07.2012
comment
Ну, что касается последней части: экземпляр server фактически обращается к ConcurrentHashMap - и уведомляет локальные рабочие потоки о новых добавленных значениях... но для простоты я выбрал Vector в моем примере - поскольку он синхронизирован дизайн (и не добавляет еще один уровень сложности к вопросу). [Правда, уровень сложности моего вопроса изначально был не таким уж высоким... как оказалось.] - person fbahr; 16.07.2012

Если сервер многопоточный, то если не синхронизировать доставку, то не гарантируется, что первое полученное сообщение будет добавлено первым.

person Reimeus    schedule 15.07.2012