简体   繁体   中英

Why ThreadLocal variable need to static?

I have read many articles on why ThreadLocal variable need to be static(although not necessary), but I didn't get the idea why it should be static.

I have read it here and many other links but didn't get the idea.

I have done something like this

public class ThreadLocalDemo{

    public static void main(String[]args)throws Exception{
        SharedRersource r1= new SharedRersource();
        Thread t1= new Thread(r1);
        Thread t2= new Thread(r1);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("Main thread Exiting...");
        }

    }

class SharedRersource implements Runnable{


        private ThreadLocal<Integer> threadId = new ThreadLocal(){
            protected Integer initialValue(){
                return (int)(Math.random()*100);
                }
        };
        public void run(){

            try{
                Thread.sleep(2000);
            }
            catch(InterruptedException e){
                e.printStackTrace();
                }
                System.out.println(threadId.get());

            }
        };

Here thread t1 and t2 is having private copy of threadId than why It should be static

Please give a better understanding to me. Thanks

Answer to this question lies into ThreadLocal implementation .

Think ThreadLocal as a container

ThreadLocal is a container that maintain a ThreadLocalMap internally , This ThreadLocalMap is the key why threadlocal need to be static(although not necessary ,but suggestion is keep it static).

Because we want single container per class , not container per instance .If we have container per instance we will be having as many container as instance and that will created memory leak .

More detail here

  1. http://www.0xcafefeed.com/2004/06/of-non-static-threadlocals-and-memory/
  2. https://www.appneta.com/blog/introduction-to-javas-threadlocal-storage/

With your implementation you have (logically) 4 different instances of threadID :

  1. r1.threadID{t1} - Instance saved in resource r1 and observed by thread t1 . It will be printed by thread t1 if it will be interrupted.

  2. r2.threadID{t2} - Instance saved in resource r2 and observed by thread t2 . It will be printed by thread t2 if it will be interrupted.

  3. r1.threadID{t2} - Instance saved in resource r1 and observed by thread t2 in case, eg, if it calls (directly) r1.run() .

  4. r2.threadID{t2} - Instance saved in resource r2 and observed by thread t1 in case, eg, if it calls (directly) r2.run() .

It is unlikely that you need 3-rd and 4-th instances, so you may:

  • Make variable static .

In that case you will have two instances : threadID{t1} , which is observed by thread t1 , and threadID{t2} , which is observed by thread t2 .

  • Make variable non-ThreadLocal .

In that case you will have two instances : r1.threadID , which is observed via r1 (by thread t1 ), and r2.threadID , which is observed via r2 (by thread t2 ).

There is no inherent reason why a ThreadLocal variable needs to be static. It's just that, the problem that ThreadLocal solves is a problem that usually only occurs in programs that are based on static-y design ideas.

IMO, you're most likely to find ThreadLocal in code that originally was single-threaded until somebody "upgraded" it to use multiple threads. Thread local comes in handy when a large body of code originally referred to some static variable, and now you need each thread that's running through the same body of code to have its own copy.

IMO, ThreadLocal is a code smell---a sign of Bad Design. A well designed, multi-threaded program should not need it.

A ThreadLocal doesn't need to be static . Just like any other variable, it depends on your intention:

public class FooClass {
  static Integer staticVar                          // 1 per process
  Integer var;                                      // 1 per instance

  static ThreadLocal<Integer> staticThreadLocalVar; // 1 per thread
  ThreadLocal<Integer> threadLocalVar;              // 1 per thread per instance
}

The quote you gave refers exactly to the third case listed above.

ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread

However, it might be perfectly reasonable in some situations to associate state with a thread per instance , in which case you would want to use a non-static ThreadLocal instead (fourth case).

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