简体   繁体   中英

Why ThreadLocal doesn't create in new thread?

The class Collector was created to generate the map with values (for example). Need that Collector contains the resource, where haves access only by the current thread.

The class Collector is presented below:

public class Collector    
    {
        ThreadLocal<Map<String, String>> storage;
        public Map<String, String> collection(int id) {
            storage = new ThreadLocal<>();
            storage.set(new HashMap<>());
            for (int i = id * 100; i <= id * 1000; i+=id * 100)
            {
                storage.get().put(String.valueOf(i), "test");
            }
            return storage.get();
        }
    }

I try to execute method collection(int id) at the same time in different threads. My suggestion is based the official documentation . But sometimes thrown NullPointerException , my observations point out on re-creating ThreadLocal by another Thread, so NullPointerException throw in the storage.get().put(String.valueOf(i), "test"); , because in the another thread in the line storage = new ThreadLocal<>(); was re-initialized.

Below presented code, where run two threads:

Collector collector = new Collector();
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                System.out.println(collector.collection(1));
            }
        }).start();
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                System.out.println(collector.collection(2));
            }
        }).start();

How I can use the ThreadLocal to have local resource in each thread, which is independence from another threads?

The problem is that you're re-creating a new ThreadLocal instance each time the

collection(int)

method is called, with

this.storage = new ThreadLocal<>();

The ThreadLocal<Map<String, String>> can be a class static field

private final static ThreadLocal<Map<String, String>> STORAGE = new ThreadLocal<>();

To set and get the Thread 's associated value, just use

// You're better off passing and using an already constructed instance
STORAGE.set(new HashMap<>());
STORAGE.get();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM