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

     

  • 相关阅读:
    不兼容结构的协调—适配器模式(三)
    Java的时间空间复杂度详解
    Java学习笔记之变量和类变量的访问哲学
    求最大公约数-辗转相除法
    java中怎么遍历HashMap
    Java编程时如何节省内存,效率高
    Java入门需掌握的30个基本概念
    Java各种获取系统当前时间方法和格式
    Java 实现顺序结构线性列表
    Java编程中异常处理的优劣之道
  • 原文地址:https://www.cnblogs.com/atomicbomb/p/9965316.html
Copyright © 2011-2022 走看看