ThreadLocal

作者: lconcise | 来源:发表于2018-12-03 21:34 被阅读10次

    最近工作涉到系统的Sass改造,我们采取的方法便是:动态的切换数据库,中间使用到ThreadLocal,以前对它并不熟悉,这里进行学习,记录下。

    什么是ThreadLocal

    看看官方文档怎么说。

    ThreadLocal
    This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).

    该类提供线程本地变量。这些变量与普通的对应变量不同之处在于,每个访问一个线程(通过其get或set方法)都有自己的、独立初始化的变量副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。

    image.png

    我的理解:
    每个线程都有自己独立的变量副本,ThreadLocal作为一个容器,存在当前线程与当前线程的变量副本,而且当前线程可以在当前线程中拿到自己的变量副本,也只能拿到自己变量副本,也就保证的变量副本之间的线程隔离。

    有不正确的地方,还希望大家指出。

    ThreadLocal 的中主要方法

    • public T get() {...}
      返回当前线程的变量副本,如果不存在,则通过initialValue()方法生成。
    • protected T initialValue() {...}
      返回当前线程变量副本初始值。
    • public void remove() {...}
      移除当前线程的变量副本.
    • public void set(T value) {...}
      设置当前线程的变量副本。

    如果大家想进一步了解,可以查看ThreadLocal的源码。
    ThreadLocal源码分析:https://blog.csdn.net/sonny543/article/details/51336457

    ThreadLocal 例子

    • example 1 返回当前线程独一无二的线程id 官方例子
     import java.util.concurrent.atomic.AtomicInteger;
    
     public 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<Integer> threadId =
             new ThreadLocal<Integer>() {
                 @Override protected Integer initialValue() {
                     return nextId.getAndIncrement();
             }
         };
    
         // Returns the current thread's unique ID, assigning it if necessary
         public static int get() {
             return threadId.get();
         }
     }
    

    测试代码

        @Test
        public void test() {
            System.out.println(ThreadId.get());
            System.out.println(ThreadId.get());
            System.out.println(ThreadId.get());
    
            new Thread(() -> {
                System.out.println(ThreadId.get());
                System.out.println(ThreadId.get());
                System.out.println(ThreadId.get());
            }).start();
        }
    

    返回结果


    image.png
    • example 2 DateFormat 工具类
      阿里巴巴 java 开发手册中推荐的 ThreadLocal 的用法
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    
    public class DateUtil {
        public static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
            @Override
            protected DateFormat initialValue() {
                return new SimpleDateFormat("yyyy-MM-dd");
            }
        };
    }
    
        @Test
        public void test2() {
            System.out.println(DateUtil.df.get().format(new Date()));
            System.out.println(DateUtil.df.get().format(new Date()));
            System.out.println(DateUtil.df.get().format(new Date()));
        }
    

    返回结果


    image.png

    参考文献:https://www.xttblog.com/?p=3087

    相关文章

      网友评论

        本文标题:ThreadLocal

        本文链接:https://www.haomeiwen.com/subject/xogktqtx.html