• ThreadLocal的简单应用


    概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

    ThreadLocal 并不能替代同步机制,两者面向的问题领域不同。

      1:同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之间进行通信的有效方式;

      2:而threadLocal是隔离多个线程的数据共享,从根本上就不在多个线程之间共享变量,这样当然不需要对多个线程进行同步了。(每个线程有单独的数据,在线程内共享,在线程外独立)

    最常见的ThreadLocal使用场景为用来解决数据库连接、Session管理等

    private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>() {
    protected Connection initialValue() {
        return DriverManager.getConnection(DB_URL);
    }
    };
     
    public static Connection getConnection() {
      return connectionHolder.get();
    }
    

    入门样例,也是解决并发中日期格式化的问题

    import java.text.SimpleDateFormat;
    import java.util.Random;
    
    public class ThreadLocalExample implements Runnable{
    
        // SimpleDateFormat is not thread-safe, so give one to each thread
        private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
            @Override
            protected SimpleDateFormat initialValue()
            {
                return new SimpleDateFormat("yyyyMMdd HHmm");
            }
        };
        
        public static void main(String[] args) throws InterruptedException {
            ThreadLocalExample obj = new ThreadLocalExample();
            for(int i=0 ; i<10; i++){
                Thread t = new Thread(obj, ""+i);
                Thread.sleep(new Random().nextInt(1000));
                t.start();
            }
        }
    
        @Override
        public void run() {
            System.out.println("Thread Name= "+Thread.currentThread().getName()+" default Formatter = "+formatter.get().toPattern());
            try {
                Thread.sleep(new Random().nextInt(1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //formatter pattern is changed here by thread, but it won't reflect to other threads
            formatter.set(new SimpleDateFormat());
            
            System.out.println("Thread Name= "+Thread.currentThread().getName()+" formatter = "+formatter.get().toPattern());
        }
    
    }
    

     输出结果:

    Thread Name= 0 default Formatter = yyyyMMdd HHmm
    Thread Name= 0 formatter = yy-M-d ah:mm
    Thread Name= 1 default Formatter = yyyyMMdd HHmm
    Thread Name= 2 default Formatter = yyyyMMdd HHmm
    Thread Name= 1 formatter = yy-M-d ah:mm
    Thread Name= 2 formatter = yy-M-d ah:mm
    Thread Name= 3 default Formatter = yyyyMMdd HHmm
    Thread Name= 4 default Formatter = yyyyMMdd HHmm
    Thread Name= 5 default Formatter = yyyyMMdd HHmm
    ...

     参考这篇对ThreadLocal有更清晰认识,https://www.cnblogs.com/zhuimengdeyuanyuan/archive/2017/10/25/7728009.html

     

  • 相关阅读:
    (二)shell中的变量
    (一)shell脚本入门
    java的动态代理机制详解
    docker学习
    一、Spring Boot 入门
    如何高效的利用博客园?
    CMake入门指南
    TortoiseSVN安装使用
    TortoiseSVN配置和使用教程
    脑电采集 地电极和参考电极的作用和区别
  • 原文地址:https://www.cnblogs.com/atomicbomb/p/9965316.html
Copyright © 2020-2023  润新知