Question

I'm having a problem with my ThreadLocal based class. Any help would be appreciated. This is a base class with a simple list of somethings:

public class ThreadLocalTest {

protected static final ThreadLocal<List<String>> thList = new ThreadLocal<List<String>>() {
    protected List<String> initialValue() {
        return new ArrayList<String>();
    }
};

public static void put(String k) {
    thList.get().add(k);
}

public static List<String> getList() {
    return thList.get();
}

}

I'm testing it in this way:

Thread th1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("------------------thread1---------------------------");
                ThreadLocalTest.put("a");
                ThreadLocalTest.put("b");
                List<String> l = ThreadLocalTest.getList();
                System.out.println(l.size());
                System.out.println("----------------------------------------------------");
            }
        });
        Thread th2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("------------------thread2---------------------------");
                ThreadLocalTest.put("c");
                List<String> l = ThreadLocalTest.getList();
                System.out.println(l.size());
                System.out.println("----------------------------------------------------");
            }
        });
        th1.run();
        th2.run();
        th1.run();
        th2.run();
        th1.run();
        th2.run();
        th1.run();
        th2.run();

So what I get is:

------------------thread1---------------------------
2
----------------------------------------------------
------------------thread2---------------------------
3
----------------------------------------------------
------------------thread1---------------------------
5
----------------------------------------------------
------------------thread2---------------------------
6
----------------------------------------------------
------------------thread1---------------------------
8
----------------------------------------------------
------------------thread2---------------------------
9
----------------------------------------------------
------------------thread1---------------------------
11
----------------------------------------------------
------------------thread2---------------------------
12
----------------------------------------------------

You see that it seems these threads actually share the very same list, but I dont understand why.

Any tips?

Was it helpful?

Solution

You invoke run() method instead of start(). run() runs in the same thread it is invoked, while start() invokes run() in a new, separate thread. In effect, all your "threads" are executed in the same thread.

OTHER TIPS

There are two issues here.

1) you can't cause a new Thread to execute by calling the run method directly. This skips the "magic" and just calls the run method within your main thread. Everything you are seeing is happening in the same thread as a result, and so there is only one single ThreadLocal list.

To cause a new Thread to execute you have to call start

2) you can't call 'start' multiple times on the same Thread, so you can't test the multiple calling you are trying. You would have to create new Thread objects each time, but this will mean, they obviously do not share the ThreadLocal variable, which I guess you are trying to test

You see that it seems these threads actually share the very same list, but I dont understand why.

The reason is that you're not actually creating any new threads. All of your code is running using the main thread (and so, the behaviour you see is completely expected).

You need to start the new thread of execution running:

Replace:

th1.run();
th2.run();
th1.run();
th2.run();
th1.run();
th2.run();
th1.run();
th2.run();

With:

th1.start();
th2.start();

Watch out when trying to interpret your output however. Since the threads will be running concurrently, the writes to the console could be intermixed.

And you cannot strart the same Thread object after it was started, you must recreate it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top