The javadoc about the class java.lang.ThreadLocal is making me confused. They are saying that each thread that access a thread-local variable has its own, independently initialized copy of the variable. Here is an example (not a true life example) who proves that variable held in a thread-local variable could be shared by many threads:
package com.mohamad.test.threadlocal;
import java.util.List;
public class ThreadLocalExample {
private static final ThreadLocal<List<Integer>> myThreadLocal = new ThreadLocal<List<Integer>>();
public static List<Integer> get() {
return (myThreadLocal.get());
}
public static void set(List<Integer> value) {
myThreadLocal.set(value);
}
}
package com.mohamad.test.threadlocal;
import java.util.ArrayList;
import java.util.List;
public class TestThreadLocal implements Runnable {
private static List<Integer> MY_TEST_LIST = new ArrayList<Integer>(){
/** The serialVersionUID */
private static final long serialVersionUID = -2419885728976816054L;
{add(1);}
};
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public void run() {
ThreadLocalExample.set(MY_TEST_LIST);
List<Integer> integers = ThreadLocalExample.get();
integers.remove(0);
System.out.println(Thread.currentThread().getName() + " finished successfully, The list's size is: " + ThreadLocalExample.get().size() + "\n");
}
/**
* @param args
*/
public static void main(String[] args) {
TestThreadLocal thread1 = new TestThreadLocal();
Thread t1 = new Thread(thread1);
t1.start();
TestThreadLocal thread2 = new TestThreadLocal();
Thread t2 = new Thread(thread2);
t2.start();
}
}
If we run this exemple, a java.lang.IndexOutOfBoundsException
will be thrown because of the MY_TEST_LIST
that is shared by thread1
and thread2
. (And as we saw, when thread1 and thread2 called the set(MY_TEST_LIST)
method of ThreadLocalExample
, that called the set method of the ThreadLocal
variable, it didn't create an independent local copy of the MY_TEST_LIST
)
If somebody has already asked this question, please give the link to the answer because i did't find anything interesting while making a research on google.
Regards,
Everything is fine. Variable hold in ThreadLocal
is local to the thread. In your case it is a reference that is local, not the list itself. Each thread has its own copy of the reference, but all these references point to the same location. In other words: each thread can keep a reference to a different List
but in your case they all point to the same one.
If you want your example to work, each ThreadLocal
should point to a different ArrayList
(a copy):
myThreadLocal.set(new ArrayList<Integer>(value));
Having ThreadLocal
s all pointing to the same object doesn't make much sense as in this case you only need a single, globally available reference.