Freddy, и правда
Freddy, ну в общем всё там нормально, не знаю даже к чему придраться
aNNiMON, монитор один, который захватывается несколько раз: synchronized (vector) { // 1 захват vector.Firstelement(); // 2 захват, будет отпущен после возврата элемента vector.removeElement(element); // еще один захват, будет отпущен после возврата из метода } // отпущен первый захват
Freddy, я не уверен, но разве методы firstElement и removeElement не создают монитор? synchronize(vector) - 1, vector.firstElement - 2 vector.removeElement - 3 Изм. aNNiMON (1.12 / 11:04) (1)
aNNiMON, хм, taskQueue для синхронизации в пуле и vector для push/pop очереди + он же в качестве this для методов вектора. А третий монитор где?
Тогда можно и Stack использовать. А то получается в блоке три монитора, не кошерно.
Oak, потобезопасность вектора гарантирует, что любой публичный его метод по отдельности корректно отработает в многопоточной системе. Но от возможных гонок состояний вектор не защищен, поэтому для операций типа get-and-remove (как в очереди) или put-if-absent нужна дополнительная синхронизация.
Freddy, но разве Vector не потокобезопасный уже сам по себе?
Нет, synchronized(vector) не лишнее. Синхронизация здесь нужна, чтобы избежать состояния гонки. Пример: пусть у нас два потока (thread1 и thread2) в пуле и одна задача task в очереди. Если не произвести синхронизацию, то возможен такой сценарий: 1. Выполняется thread1, вызывающий pop() и исполнивший строку
3. Thread2 вызывает pop() и получает так же задачу task(!), поскольку первый поток не успел её удалить. Получается, что два разных потока получили одну и ту же задачу == трудноуловимый гейзенбаг в приложении и куча времени на отладку. У Дага Ли в Concurrency In Practice подобные вещи в пятой главе подробно раскрываются.
aNNiMON, да, насчёт wait/notify допустил просчёт Или можно заменить вектор на стек, тогда можно оставить synchronized Изм. Oak (30.11 / 19:19) (1) Java Категории |