यदि आप पूर्ण सिंक्रनाइज़ेशन की तुलना में बेहतर समेकन चाहते हैं, तो बैकिंग मैप के रूप में एक ConcurrentHashMap का उपयोग करके मुझे ऐसा करने का एक तरीका है। निम्नलिखित केवल एक स्केच है।
public final class ConcurrentHashSet<E> extends ForwardingSet<E>
implements Set<E>, Queue<E> {
private enum Dummy { VALUE }
private final ConcurrentMap<E, Dummy> map;
ConcurrentHashSet(ConcurrentMap<E, Dummy> map) {
super(map.keySet());
this.map = Preconditions.checkNotNull(map);
}
@Override public boolean add(E element) {
return map.put(element, Dummy.VALUE) == null;
}
@Override public boolean addAll(Collection<? extends E> newElements) {
// just the standard implementation
boolean modified = false;
for (E element : newElements) {
modified |= add(element);
}
return modified;
}
@Override public boolean offer(E element) {
return add(element);
}
@Override public E remove() {
E polled = poll();
if (polled == null) {
throw new NoSuchElementException();
}
return polled;
}
@Override public E poll() {
for (E element : this) {
// Not convinced that removing via iterator is viable (check this?)
if (map.remove(element) != null) {
return element;
}
}
return null;
}
@Override public E element() {
return iterator().next();
}
@Override public E peek() {
Iterator<E> iterator = iterator();
return iterator.hasNext() ? iterator.next() : null;
}
}
सभी इस दृष्टिकोण के साथ धूप नहीं है। बैकिंग मैप के entrySet().iterator().next()
का उपयोग करने के अलावा हमारे पास कोई मुख्य तत्व चुनने का कोई अच्छा तरीका नहीं है, नतीजा यह है कि समय चलने पर नक्शा अधिक से अधिक असंतुलित हो जाता है। यह असंतुलन दोनों बाल्टी टकराव और अधिक सेगमेंट विवाद के कारण एक समस्या है।
नोट: यह कोड कुछ स्थानों पर Guava का उपयोग करता है।
स्रोत
2010-06-25 21:06:10
दुर्भाग्य से यह शब्द "कतार" अस्पष्ट है, जैसा कि कुछ पाठकों के लिए यह परोक्ष अर्थ है "फीफो कतार", जबकि अन्य लोगों के लिए इसमें अधिक सामान्य 'java.util.Queue' अर्थ है, जिसका मूल रूप से कोई भी संग्रह है जिसका अर्थ है * कुछ तत्व "तत्व" की अवधारणा है, चाहे वह तत्व पहले या नहीं है। इसलिए! जो यह है? –
फीफो, ओमिशन के बारे में खेद है =) –