Размер ConcurrentLinkedQueue
Чтение Java ConcurrentLinkedQueue Docs, интересно, почему реализация не может сохранить размер:
Остерегайтесь того, что, в отличие от большинства коллекций, метод размера НЕ является операцией постоянного времени. Из-за асинхронности этих очередей определение текущего количества элементов требует обхода элементов.
Где в источник - это "асинхронный характер"?
Я вижу только цикл while, чтобы повторять enqueing, пока AtomicReferences не будет соответствовать ожидаемым значениям/ссылкам. Почему невозможно увеличить значение size:AtomicInteger
после успешного создания значения в очереди?
Спасибо большое.
Ответы
Ответ 1
Представьте, что у вас есть два потока: один добавляет новый элемент, а другой - элемент. В начале нет элементов в очереди.
Предположим, что первый поток добавляет элемент, сразу же за ним следует другой поток, удаляющий элемент и уменьшающий размер, с которого ваш размер равен -1, тогда первый поток увеличивает размер до 0.
Немного надуманный пример, но вам нужно сделать всю операцию атомарной, чтобы гарантировать, что ни один другой поток не сможет получить доступ к размеру -1.
Ответ 2
Одним из важных преимуществ производительности ConcurrentLinkedQueue
является тот факт, что вы не беспокоитесь о хвосте, когда вы обновляете голову, и наоборот, правильно?
Это означает, что в основном 2 потока могут опросить/предложить одновременно без вмешательства (если размер очереди не был 0, то есть).
Это было не так, если у вас был счетчик. Даже если это был AtomicInteger
, который имеет хороший concurrency, у вас все еще будет повышенная вероятность неудачных операций CAS, потому что теперь у вас есть эта "горячая точка", которую вы обновляете каждый раз, когда вы проводите опрос/предложение.
Не совсем уверен, что авторы означают это, когда говорят "асинхронный характер", но я думаю, что это самая большая причина, по которой они не имеют счетчика, как вы предполагали.
Ответ 3
Почему невозможно увеличить размер: AtomicInteger после успешного завершения предлагая значение для очереди?
Возможно, потому что это предложение/декремент не может быть выполнено атомарно, не отрицательно влияя на метод concurrency метода.