Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java: Общие вопросы > Почему ConcurrentHashMap#containsValue() |
Автор: Royan 29.7.2008, 15:07 | ||||
Задаю вопрос по человечески. Обнаружил, что аналигичные по своему смыслу методы в совершенно разных по смыслу классах реализованы по разному. Пример: PriorityBlockingQueue.contains(Object):
ConcurrentHashMap.Segment.containsKey(Object)
Не вдаваясь в детали реализации сразу видно, что методы не меняющие состояния объекта (containsKey, containsValue, get) в ConcurrentHashMap лишины какой бы то нибыло синхронизации, в то время как в PriorityBlockingQueue аналогичные (не меняющие состояния очереди) методы (size(), contains()) синхронизированы. Вопрос почему? |
Автор: Platon 29.7.2008, 15:39 |
Я думаю, это связано с внутренней реализацией PriorityQueue Там оочень важна синхронизация, т.к. есть возможность получить ArrayIndexOutOfBoundsException |
Автор: yaja 29.7.2008, 16:02 |
Стоит почитать java-doc к этим классам. ConcurrentHashMap не гарантирует синхронность данных. Если операция чтения совпадает с операцией изменения структуры, то ты эти изменения можешь не увидеть. Гарантируется только безопасность работы со структурой из нескольких потоков, чего нету у стандартных HashMap'ов. |
Автор: COVD 29.7.2008, 18:30 | ||
Royan, вы сами и ответили на свой вопрос - реализовано по-разному потому, что это "разные по смыслу классы". Один - очередь на основе связанного списка. Другой - мап, т.е. массив. |
Автор: ivg 29.7.2008, 18:53 |
Короче суть в том, что методы записи ConcurrentHashMap, возможно вкупе с методами чтения, реализованы таким образом, что в любой момент переключения потоков, логическая целостность объекта ConcurrentHashMap, как такового(имеется ввиду непротиворечивость состояния внутренних полей), гарантируется. В отличии от объекта класса PriorityQueue, для которого PriorityBlockingQueue является просто синхронизированной обёрткой. |
Автор: Royan 29.7.2008, 19:02 | ||
Я не нахожу ответа на вопрос, почему если мап то можно кое-что не синхронизировать, а если очередь (не важно на какой основе, ибо все что отростает от AbstractQueue синхронизировано вдоль и поперек) так вот если очередь то, как я говорил, надо ее насквозь залочить. |
Автор: COVD 29.7.2008, 20:58 | ||
Ну, наверное, потому, что методы, изменяющие обьект, по-разному меняют структуру. Например, при удалении элемента в мапе значение массива в соответствующем индексе просто становится равно null. А в связанном списке при удалении обнуляются ссылки на следующие элементы. Последствия при итерации возможно будут разные, если не синхронизировать. Или еще что-то. Это следствие оптимизации классов с учетом нюансов структуры. |
Автор: Royan 30.7.2008, 15:56 | ||
Похоже на то |