2015-05-19 20 views
5

gibi ConcurrentLinkedQueue, ConcurrentLinkedDequeue ve ConcurrentSkipListSet aşağıdaki reddi ile gelen Java standart kütüphanesindeki en koleksiyonların belgeler: Çoğu koleksiyonlarında farklı olarakEşzamanlı toplama boyutu hesaplama

sakının, boyut yöntemi değil sabit zamanlı çalışma. Bu kümelerinin asenkron doğası nedeniyle, geçerli eleman sayısını belirlemek, öğelerin geçişini gerektirir ve bu nedenle, bu koleksiyonu geçiş sırasında değiştirilirse hatalı sonuçlar bildirebilir.

Bu ne anlama geliyor? Neden bir sayaç tutmuyorlar (örneğin, bir AtomicInteger) ve sadece size() numarasına yapılan çağrıları geri getiremiyorlar?

Sayacın senkronize olması ve bu nedenle bir tıkama noktası oluşturması nedeniyle mi?

Bir yan not olarak, ConcurrentHashMap bu sorun yok gibi görünüyor. Neden? Kaynak koduna bakıldığında, size() numaralı çağrılara toplanan bir dizide tutulan çoklu sayıcıları kullanıyor gibi görünüyor. Boğaz noktasını atlatmak mı yoksa başka bir sebep mi var?

+0

kesinlikle kötü olurdu. – ZhongYu

cevap

5

Boyutu() korumak için paylaşılan bir kaynak kullanmak hem pahalı hem de oldukça işe yaramaz olacaktır. size(), koleksiyon üzerinde bir kilit tutamayacağınız için döndüğünüzde ve değeri aldığınızda aramanız arasında geçiş yapabilmesi için geri döndüğü anda yanlış olabilir.

ConcurentHashMap aynı yaklaşıma sahiptir. Yöntem döndürülmeden önce() boyutu yanlış olabilir. Bir atomik sayıcı

+0

Elbette 'size()' tam olarak güvenilemez, bunu kabul ediyorum. Ama sahip olduğum problem, koleksiyondaki her bir unsuru saymak için sabit olmayan bir maliyettir. Ama sanırım o zaman jikle hakkında haklı mıydım? –

+1

@GustavKarlsson Peter'ın ilk cümlesi, gerçekten nedenini ele alıyor. Senkronizasyon ve önbellek geçersiz kılma bir kuyruğun çalışması için çok maliyetli olacaktır. Evet haklıydın, orada bir şişe boynu olmalıydı. ReentrantReadWriteLock ile ilgili temel sorunlardan biri de budur. –