zoukankan      html  css  js  c++  java
  • 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

     

  • 相关阅读:
    Python学习 :面向对象 -- 三大特性
    Python学习 :面向对象(一)
    小米oj #40 找小“3”
    第三次作业
    排序算法模板
    树状数组求逆序数
    最短路模板
    字典树模板
    LCS
    多项式朴素乘法
  • 原文地址:https://www.cnblogs.com/atomicbomb/p/9965316.html
Copyright © 2011-2022 走看看