553  Oak [Off]
 Эль Презеденте
(1.12.2014 / 12:24)
Freddy, и правда
1  aNNiMON (SV!) [Off]
 let live
(1.12.2014 / 11:41)
Freddy, ну в общем всё там нормально, не знаю даже к чему придраться :-D
107  Freddy [Off]
(1.12.2014 / 11:28)
aNNiMON, монитор один, который захватывается несколько раз:
synchronized (vector) { // 1 захват
     vector.Firstelement(); // 2 захват, будет отпущен после возврата элемента
     vector.removeElement(element); // еще один захват, будет отпущен после возврата из метода
} // отпущен первый захват
1  aNNiMON (SV!) [Off]
 let live
(1.12.2014 / 11:02)
Freddy, я не уверен, но разве методы firstElement и removeElement не создают монитор?
synchronize(vector) - 1,
vector.firstElement - 2
vector.removeElement - 3
Изм. aNNiMON (1.12 / 11:04) (1)
107  Freddy [Off]
(1.12.2014 / 10:46)
aNNiMON, хм, taskQueue для синхронизации в пуле и vector для push/pop очереди + он же в качестве this для методов вектора. А третий монитор где?
1  aNNiMON (SV!) [Off]
 let live
(1.12.2014 / 09:42)
Тогда можно и Stack использовать. А то получается в блоке три монитора, не кошерно.
107  Freddy [Off]
(1.12.2014 / 08:20)
Oak, потобезопасность вектора гарантирует, что любой публичный его метод по отдельности корректно отработает в многопоточной системе. Но от возможных гонок состояний вектор не защищен, поэтому для операций типа get-and-remove (как в очереди) или put-if-absent нужна дополнительная синхронизация.
553  Oak [Off]
 Эль Презеденте
(1.12.2014 / 06:42)
Freddy, но разве Vector не потокобезопасный уже сам по себе?
107  Freddy [Off]
(30.11.2014 / 20:48)
Нет, synchronized(vector) не лишнее. Синхронизация здесь нужна, чтобы избежать состояния гонки. Пример: пусть у нас два потока (thread1 и thread2) в пуле и одна задача task в очереди. Если не произвести синхронизацию, то возможен такой сценарий:
1. Выполняется thread1, вызывающий pop() и исполнивший строку
  1. Runnable r = (Runnable)vector.firstElement();
2. У потока thread1 заканчивается квант времени, система переключается на thread2.
3. Thread2 вызывает pop() и получает так же задачу task(!), поскольку первый поток не успел её удалить.
Получается, что два разных потока получили одну и ту же задачу == трудноуловимый гейзенбаг в приложении и куча времени на отладку.

У Дага Ли в Concurrency In Practice подобные вещи в пятой главе подробно раскрываются.
553  Oak [Off]
 Эль Презеденте
(30.11.2014 / 19:18)
aNNiMON, да, насчёт wait/notify допустил просчёт

Или можно заменить вектор на стек, тогда можно оставить synchronized
Изм. Oak (30.11 / 19:19) (1)
Всего: 19
1 2 >>
К записи
Java
Категории

Мы в соцсетях

tw tg yt gt