Pull to refresh

Comments 7

StampedLock будет эффективнее ReentrantReadWriteLock за счёт того, что в случае успеха оптимистичной блокировки (fast path) вообще не происходит обновления разделяемых переменных, в то время как ReentrantReadWriteLock даже в лучшем случае выполняет как минимум один CAS.

По-моему, тут нельзя использовать StampedLock в оптимистическом режиме. В него можно оборачивать только чтение полей, но не произвольный код.

     long stamp = sl.tryOptimisticRead();
     int ret = buf.get(offset);
     if (!sl.validate(stamp)) {
         // lock and re-read (slow path)
     }
     return ret;

Если писатель пришел после того, как мы вызвали tryOptimisticRead(), но до того, как мы вызвали validate(), то buf.get() и buf.put() могут быть вызваны одновременно, что может быть проблемой, в зависимости от внутренней реализации класса ByteBuffer. Если бы вместо buf.get() и buf.put() были бы явное чтение/запись из массива, не было бы проблем.

Поэтому лучше не выпендриваться использованием низкоуровневых примитивов синхронизации и использовать обычный мьютекс.

В данном случае как раз используются версии get(int index) и putInt(int index, int value) по абсолютному index, которые реализованы в HeapByteBuffer как явное чтение/запись из массива (в DirectByteBuffer — как чтение/запись из памяти), поэтому проблем нет.

В задаче со стримами использование raw-type и объектного стрима для примитивного типа никого не напрягло?


Кстати, более интересный вопрос, как исправить код, чтобы получить желаемый результат, при условии, что сигнатура метода фиксирована.

Первоначальная задумка была как раз исправить, но было бы уже многовато задач на написание кода для такого формата. Впрочем, несколько участников всё равно написали свой вариант с summaryStatistics(), получив в итоге полный балл за задачу.
В исходниках одной малоизвестной игры обнаружился такой код.

Олдскульным фанатам драконов и элементалей — моё почтение!

Sign up to leave a comment.