I have a static HashSet of object references in my code, which has to disallow all write requests until a given method is running (which uses the hashset only for read purpose开发者_如何学Cs). I have read the Thread basics but am yet not clear how to proceed doing this.
Can anyone please help me out ?
You mentioned that you have read the Thread basics, so I assume you have a multi-threaded app where you have multiple readers and/or writers to the set. You could use a read-write lock to restrict access to the collection. When the given method executes, it locks the read lock, which allows others to read, but not to write. As long as you write using the putInSet
method (or something similar) below, you can require the write lock to write to. Then the set cannot be written to while the read lock is being held.
private final Set<Object> mySet = new HashSet<Object>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public void methodThatRunsAndAllowsReadOnly() {
lock.readLock().lock();
try {
// method body here
}
finally {
lock.readLock().unlock();
}
}
public void putInSet(Object o) {
lock.writeLock().lock();
try {
mySet.add(o);
}
finally {
lock.writeLock().unlock();
}
}
You can create a read-only view of the set by using Collections.unmodifiableSet
. Just pass this view to everyone who doesn't need to write to the set. (An UnsupportedOperationException
will be thrown for anybody who tries to modify this view.)
This is an interesting question, normally it is the other way around.
If you want an immutable map till some magic method tells the rest of the application that it is ok you can use Collections.unmodifiableMap()
to create an Immutable copy of your map after initialisation.
When the magic method runs, it can replace the map with a modifiable copy again.
Map myMap;
public MyClass(Map myMap) {
this.myMap = Collections.unmodifiableMap(myMap);
}
synchronized public void releaseMyMap() {
myMap = new HashMap(myMap);
}
You can extend from a Set and provide your own lock based implementation (of add) to read and write to the Set.
This will ensure that whenever a thread is reading (after acquiring the lock) no other thread can write to it.
No exactly sure what is the problem, but if you are just trying to avoid concurrency issues with access to with HashSet, probably worth looking at ConcurrentSkipListSet. It takes log(n) time for the most of operations, but it doesn't require synchronization and doesn't block on insertion, removal, and access operations. In the whole that may give you better performance.
精彩评论