All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.engio.mbassy.common.WeakConcurrentSet Maven / Gradle / Ivy

package net.engio.mbassy.common;


import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.WeakHashMap;
import java.util.concurrent.locks.Lock;

/**
 * This implementation uses weak references to the elements. Iterators automatically perform cleanups of
 * garbage collected objects during iteration -> no dedicated maintenance operations need to be called or run in background.
 * 

*

*

* * @author bennidi * Date: 2/12/12 */ public class WeakConcurrentSet extends AbstractConcurrentSet{ public WeakConcurrentSet() { super(new WeakHashMap>()); } public Iterator iterator() { return new Iterator() { // the current listelement of this iterator // used to keep track of the iteration process private ISetEntry current = head; // this method will remove all orphaned entries // until it finds the first entry whose value has not yet been garbage collected // the method assumes that the current element is already orphaned and will remove it private void removeOrphans(){ Lock writelock = lock.writeLock(); try{ writelock.lock(); do { ISetEntry orphaned = current; current = current.next(); if (orphaned == head) { head = head.next(); } orphaned.remove(); } while(current != null && current.getValue() == null); } finally { writelock.unlock(); } } public boolean hasNext() { if (current == null) return false; if (current.getValue() == null) { // trigger removal of orphan references // because a null value indicates that the value has been garbage collected removeOrphans(); return current != null; // if any entry is left then it will have a value } else { return true; } } public T next() { if (current == null) { return null; } T value = current.getValue(); if (value == null) { // auto-removal of orphan references removeOrphans(); return next(); } else { current = current.next(); return value; } } public void remove() { //throw new UnsupportedOperationException("Explicit removal of set elements is only allowed via the controlling set. Sorry!"); if (current == null) { return; } ISetEntry newCurrent = current.next(); WeakConcurrentSet.this.remove(current.getValue()); current = newCurrent; } }; } @Override protected Entry createEntry(T value, Entry next) { return next != null ? new WeakEntry(value, next) : new WeakEntry(value); } public static class WeakEntry extends Entry { private WeakReference value; private WeakEntry(T value, Entry next) { super(next); this.value = new WeakReference(value); } private WeakEntry(T value) { super(); this.value = new WeakReference(value); } @Override public T getValue() { return value.get(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy