Making Instance Variables Thread Safe

One of the ways to achieve thread safety when creating instance variables is to make a use of ThreadLocal class.  When instance variable is wrapped in ThreadLocal, each thread accessing the variable has its own independent copy of the variable.

An even better approach is to wrap the instance variable in SoftReference, which can eliminate the risk if getting OutOfMemoryError if there is a need to keep a an object in memory for a long period of time, for example when implementing caching mechanism. The garbage collector will only collect softly referenced objects when it decides that memory is low enough to warrant it

Consider the following snippet:

[java]
public class ThreadSafeExample {

private static final ThreadLocal<SoftReference<List<SomeObject>>> trhLocal =
new ThreadLocal<SoftReference<List<SomeObject>>>();
.
.
public static List<SomeObject> getSafeList() {

// Get the value of the current thread’s copy of this thread-local variable
SoftReference<List<SomeObject>> reference = trhLocal.get();

if (reference != null) {
// Get this reference object’s referent
List<SomeObject> safeList = reference.get();

if (safeList != null) {
return safeList;
}
}

// Ok, so we did not have previously anything,
// lets create thread-local variable
List<SomeObject> safeList = new LinkedList<SomeObject>();
reference = new SoftReference<List<SomeObject>>(safeList);
trhLocal.set(reference);

return safeList;
}
}
[/java]

What happens in the above example is, when getSafeList() is called, the thread’s list is assigned the first time it invokes getSafeList(), which causes invocation of  trhLocal.get().  If get() does not return anything, a new copy of the instance variable is created and set to the ThreadLocal instance. Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible. This approach does not require  synchronization, which can create thread contention, and provides much faster access to the variable than via synchronization.

Off course one should consider whether ThreadLocal is really needed. Normally, a good candidates for object re-use via thread local are objects that are frequently accessed by a given thread and are non-trivial to construct. Another scenario for making use of ThreadLocal, would be when it is not really practical to extend Thread class (for example creating servlets) and thread safety is needed.

Brainteaser: Hidden Iterators

… While locking can prevent iterators from throwing ConcurrentMofdificationException, You have to remember to use locking everywhere a shared collection might be iterated. This is trickier than it sounds …

Brian Goetz p.83-84

Question: The following code could throw ConcurrentMofdificationException, even though add() is synchronized, why?

[java]
public class HiddenIterator {
private final Set set = new HashSet();

public synchronized void add(Integer i) {
set.add(i);
}

public synchronized void remove(Integer i) {
set.remove(i);
}

public void addTenThings() {
Random r = new Random();
for (int index = 0; index &lt; 10; index++;) {
add(r.nextInt());
}

System.out.println("Added ten elements to set: " + set);
}
}
[/java]

Looking forward for your answers dear readers