-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Added the SealableXXX collection classes.
- Strengthened the implementation of ConcurrentList and ConcurrentHashSet. - Renamed ConcurrentHashSet to ConcurrentSet
- Loading branch information
Showing
14 changed files
with
318 additions
and
263 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,10 +28,10 @@ | |
* entrySet() APIs return the original Strings, not the internally | ||
* wrapped CaseInsensitiveString. | ||
* | ||
* As an added benefit, .keySet() returns a case-insenstive | ||
* As an added benefit, .keySet() returns a case-insensitive | ||
* Set, however, again, the contents of the entries are actual Strings. | ||
* Similarly, .entrySet() returns a case-insensitive entry set, such that | ||
* .getKey() on the entry is case insensitive when compared, but the | ||
* .getKey() on the entry is case-insensitive when compared, but the | ||
* returned key is a String. | ||
* | ||
* @author John DeRegnaucourt ([email protected]) | ||
|
@@ -314,11 +314,13 @@ public Collection<V> values() | |
return map.values(); | ||
} | ||
|
||
@Deprecated | ||
public Map minus(Object removeMe) | ||
{ | ||
throw new UnsupportedOperationException("Unsupported operation [minus] or [-] between Maps. Use removeAll() or retainAll() instead."); | ||
} | ||
|
||
@Deprecated | ||
public Map plus(Object right) | ||
{ | ||
throw new UnsupportedOperationException("Unsupported operation [plus] or [+] between Maps. Use putAll() instead."); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 0 additions & 79 deletions
79
src/main/java/com/cedarsoftware/util/ConcurrentHashSet.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,17 +2,23 @@ | |
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.HashSet; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
import java.util.ListIterator; | ||
import java.util.concurrent.locks.ReadWriteLock; | ||
import java.util.concurrent.locks.ReentrantReadWriteLock; | ||
|
||
/** | ||
* ConcurrentList provides a List or List wrapper that is thread-safe, usable in highly concurrent | ||
* ConcurrentList provides a List and List wrapper that is thread-safe, usable in highly concurrent | ||
* environments. It provides a no-arg constructor that will directly return a ConcurrentList that is | ||
* thread-safe. It has a constructor that takes a List argument, which will wrap that List and make it | ||
* thread-safe (no elements are duplicated). | ||
* thread-safe (no elements are duplicated).<br> | ||
* <br> | ||
* The iterator(), listIterator() return read-only views copied from the list. The listIterator(index) | ||
* is not implemented, as the inbound index could already be outside the lists position due to concurrent | ||
* edits. Similarly, subList(from, to) is not implemented because the boundaries may exceed the lists | ||
* size due to concurrent edits. | ||
* <br><br> | ||
* @author John DeRegnaucourt ([email protected]) | ||
* <br> | ||
|
@@ -32,12 +38,13 @@ | |
*/ | ||
public class ConcurrentList<E> implements List<E> { | ||
private final List<E> list; | ||
private final ReadWriteLock lock = new ReentrantReadWriteLock(); | ||
private final ReadWriteLock lock; | ||
|
||
/** | ||
* Use this no-arg constructor to create a ConcurrentList. | ||
*/ | ||
public ConcurrentList() { | ||
lock = new ReentrantReadWriteLock(); | ||
this.list = new ArrayList<>(); | ||
} | ||
|
||
|
@@ -50,6 +57,7 @@ public ConcurrentList(List<E> list) { | |
if (list == null) { | ||
throw new IllegalArgumentException("list cannot be null"); | ||
} | ||
lock = new ReentrantReadWriteLock(); | ||
this.list = list; | ||
} | ||
|
||
|
@@ -89,6 +97,15 @@ public int hashCode() { | |
} | ||
} | ||
|
||
public String toString() { | ||
lock.readLock().lock(); | ||
try { | ||
return list.toString(); | ||
} finally { | ||
lock.readLock().unlock(); | ||
} | ||
} | ||
|
||
public boolean contains(Object o) { | ||
lock.readLock().lock(); | ||
try { | ||
|
@@ -101,7 +118,7 @@ public boolean contains(Object o) { | |
public Iterator<E> iterator() { | ||
lock.readLock().lock(); | ||
try { | ||
return new ArrayList<>(list).iterator(); // Create a snapshot for iterator | ||
return new ArrayList<>(list).iterator(); | ||
} finally { | ||
lock.readLock().unlock(); | ||
} | ||
|
@@ -146,7 +163,7 @@ public boolean remove(Object o) { | |
public boolean containsAll(Collection<?> c) { | ||
lock.readLock().lock(); | ||
try { | ||
return list.containsAll(c); | ||
return new HashSet<>(list).containsAll(c); | ||
} finally { | ||
lock.readLock().unlock(); | ||
} | ||
|
@@ -251,90 +268,20 @@ public int lastIndexOf(Object o) { | |
} | ||
} | ||
|
||
public List<E> subList(int fromIndex, int toIndex) { return new ConcurrentList<>(list.subList(fromIndex, toIndex)); } | ||
public List<E> subList(int fromIndex, int toIndex) { | ||
throw new UnsupportedOperationException("subList not implemented for ConcurrentList"); | ||
} | ||
|
||
public ListIterator<E> listIterator() { | ||
return createLockHonoringListIterator(list.listIterator()); | ||
lock.readLock().lock(); | ||
try { | ||
return new ArrayList<E>(list).listIterator(); | ||
} finally { | ||
lock.readLock().unlock(); | ||
} | ||
} | ||
|
||
public ListIterator<E> listIterator(int index) { | ||
return createLockHonoringListIterator(list.listIterator(index)); | ||
} | ||
|
||
private ListIterator<E> createLockHonoringListIterator(ListIterator<E> iterator) { | ||
return new ListIterator<E>() { | ||
public boolean hasNext() { | ||
lock.readLock().lock(); | ||
try { | ||
return iterator.hasNext(); | ||
} finally { | ||
lock.readLock().unlock(); | ||
} | ||
} | ||
public E next() { | ||
lock.readLock().lock(); | ||
try { | ||
return iterator.next(); | ||
} finally { | ||
lock.readLock().unlock(); | ||
} | ||
} | ||
public boolean hasPrevious() { | ||
lock.readLock().lock(); | ||
try { | ||
return iterator.hasPrevious(); | ||
} finally { | ||
lock.readLock().unlock(); | ||
} | ||
} | ||
public E previous() { | ||
lock.readLock().lock(); | ||
try { | ||
return iterator.previous(); | ||
} finally { | ||
lock.readLock().unlock(); | ||
} | ||
} | ||
public int nextIndex() { | ||
lock.readLock().lock(); | ||
try { | ||
return iterator.nextIndex(); | ||
} finally { | ||
lock.readLock().unlock(); | ||
} | ||
} | ||
public int previousIndex() { | ||
lock.readLock().lock(); | ||
try { | ||
return iterator.previousIndex(); | ||
} finally { | ||
lock.readLock().unlock(); | ||
} | ||
} | ||
public void remove() { | ||
lock.writeLock().lock(); | ||
try { | ||
iterator.remove(); | ||
} finally { | ||
lock.writeLock().unlock(); | ||
} | ||
} | ||
public void set(E e) { | ||
lock.writeLock().lock(); | ||
try { | ||
iterator.set(e); | ||
} finally { | ||
lock.writeLock().unlock(); | ||
} | ||
} | ||
public void add(E e) { | ||
lock.writeLock().lock(); | ||
try { | ||
iterator.add(e); | ||
} finally { | ||
lock.writeLock().unlock(); | ||
} | ||
} | ||
}; | ||
throw new UnsupportedOperationException("listIterator(index) not implemented for ConcurrentList"); | ||
} | ||
} | ||
} |
Oops, something went wrong.