Mercurial > hg > blitz_condensed
diff src/EDU/oswego/cs/dl/util/concurrent/CopyOnWriteArraySet.java @ 0:3dc0c5604566
Initial checkin of blitz 2.0 fcs - no installer yet.
author | Dan Creswell <dan.creswell@gmail.com> |
---|---|
date | Sat, 21 Mar 2009 11:00:06 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/EDU/oswego/cs/dl/util/concurrent/CopyOnWriteArraySet.java Sat Mar 21 11:00:06 2009 +0000 @@ -0,0 +1,102 @@ +/* + File: CopyOnWriteArraySet.java + + Originally written by Doug Lea and released into the public domain. + This may be used for any purposes whatsoever without acknowledgment. + Thanks for the assistance and support of Sun Microsystems Labs, + and everyone contributing, testing, and using this code. + + History: + Date Who What + 22Jun1998 dl Create public version +*/ + +package EDU.oswego.cs.dl.util.concurrent; +import java.util.*; + +/** + * This class implements a java.util.Set that uses a + * CopyOnWriteArrayList for all of its operations. + * Thus, it shares the same basic properties: + * <ul> + * <li> It is best suited for applications in which set sizes generally + * stay small, read-only operations + * vastly outnumber mutative operations, and you need + * to prevent interference among threads during traversal. + * <li> Mutative operations(add, set, remove, etc) are fairly expensive + * since they usually entail copying the entire underlying array. + * <li> Loops involving repeated element-by-element mutative operations + * are so expensive that they should generally be avoided. + * <li> Iterators do not support the mutative remove operation + * <li> Traversal via iterators is very fast and cannot ever encounter + * interference from other threads. Iterators rely on + * unchanging snapshots of the array at the time the iterators were + * constructed + * </ul> + * <p> + * <b>Sample Usage.</b> Probably the main application + * of copy-on-write sets are classes that maintain + * sets of Handler objects + * that must be multicasted to upon an update command. This + * is a classic case where you do not want to be holding a synch + * lock while sending a message, and where traversals normally + * vastly overwhelm additions. + * <pre> + * class Handler { void handle(); ... } + * + * class X { + * private final CopyOnWriteArraySet handlers = new CopyOnWriteArraySet(); + * public void addHandler(Handler h) { handlers.add(h); } + * + * private long internalState; + * private synchronized void changeState() { internalState = ...; } + * + * public void update() { + * changeState(); + * Iterator it = handlers.iterator(); + * while (it.hasNext()) + * ((Handler)(it.next()).handle(); + * } + * } + * </pre> + * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>] + * @see CopyOnWriteArrayList + **/ + + +public class CopyOnWriteArraySet extends AbstractSet implements Cloneable, java.io.Serializable { + + protected final CopyOnWriteArrayList al; + + /** + * Constructs an empty set + */ + public CopyOnWriteArraySet() { + al = new CopyOnWriteArrayList(); + } + + /** + * Constructs a set containing all of the elements of the specified + * Collection. + */ + public CopyOnWriteArraySet(Collection c) { + al = new CopyOnWriteArrayList(); + al.addAllAbsent(c); + } + + + public int size() { return al.size(); } + public boolean isEmpty() { return al.isEmpty(); } + public boolean contains(Object o) { return al.contains(o); } + public Object[] toArray() { return al.toArray(); } + public Object[] toArray(Object[] a) { return al.toArray(a); } + public void clear() { al.clear(); } + public Iterator iterator() { return al.iterator(); } + public boolean remove(Object o) { return al.remove(o); } + public boolean containsAll(Collection c) { return al.containsAll(c); } + public boolean addAll(Collection c) { return al.addAllAbsent(c) > 0; } + public boolean removeAll(Collection c) { return al.removeAll(c); } + public boolean retainAll(Collection c) { return al.retainAll(c); } + public boolean add(Object o) { return al.addIfAbsent(o); } + +}