views:

113

answers:

5

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 purposes). I have read the Thread basics but am yet not clear how to proceed doing this.

Can anyone please help me out ?

+4  A: 

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.)

Chris Jester-Young
+1  A: 

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);
}
Peter Tillemans
+8  A: 

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();
    }
 }
Jeff Storey
+1 for using read-write locks.
Chris Jester-Young
A: 

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.

Nrj
A: 

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.

Stas