When and how should I use a ThreadLocal variable?

前端 未结 25 2274
再見小時候
再見小時候 2020-11-22 12:35

When should I use a ThreadLocal variable?

How is it used?

25条回答
  •  难免孤独
    2020-11-22 12:59

    Two use cases where threadlocal variable can be used -
    1- When we have a requirement to associate state with a thread (e.g., a user ID or Transaction ID). That usually happens with a web application that every request going to a servlet has a unique transactionID associated with it.

    // This class will provide a thread local variable which
    // will provide a unique ID for each thread
    class ThreadId {
        // Atomic integer containing the next thread ID to be assigned
        private static final AtomicInteger nextId = new AtomicInteger(0);
    
        // Thread local variable containing each thread's ID
        private static final ThreadLocal threadId =
            ThreadLocal.withInitial(()-> {return nextId.getAndIncrement();});
    
        // Returns the current thread's unique ID, assigning it if necessary
        public static int get() {
            return threadId.get();
        }
    }
    

    Note that here the method withInitial is implemented using lambda expression.
    2- Another use case is when we want to have a thread safe instance and we don't want to use synchronization as the performance cost with synchronization is more. One such case is when SimpleDateFormat is used. Since SimpleDateFormat is not thread safe so we have to provide mechanism to make it thread safe.

    public class ThreadLocalDemo1 implements Runnable {
        // threadlocal variable is created
        private static final ThreadLocal dateFormat = new ThreadLocal(){
            @Override
            protected SimpleDateFormat initialValue(){
                System.out.println("Initializing SimpleDateFormat for - " + Thread.currentThread().getName() );
                return new SimpleDateFormat("dd/MM/yyyy");
            }
        };
    
        public static void main(String[] args) {
            ThreadLocalDemo1 td = new ThreadLocalDemo1();
            // Two threads are created
            Thread t1 = new Thread(td, "Thread-1");
            Thread t2 = new Thread(td, "Thread-2");
            t1.start();
            t2.start();
        }
    
        @Override
        public void run() {
            System.out.println("Thread run execution started for " + Thread.currentThread().getName());
            System.out.println("Date formatter pattern is  " + dateFormat.get().toPattern());
            System.out.println("Formatted date is " + dateFormat.get().format(new Date()));
        } 
    
    }
    

提交回复
热议问题