• 多线程:ThreadLocal的基本使用


    1、ThreadLocal初识

      从Java官方文档中的描述:ThreadLocal类用来提供线程内部的局部变量。这种变量在多线程环境下访问(通过get和set方法访问)时能保证各个线程的变量相对独立于其他线程内的变量。ThreadLocal实例通常来说都是private static类型的,用于关联线程和线程上下文。
      我们可以得知ThreadLocal的作用是∶提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂度。

    • 线程并发:ThreadLocal只在多线程的环境下起作用
    • 传递数据:我们可以通过ThreadLocal在同一线程不同组件中传递公共数据
    • 线程隔离:每一个线程的变量都是独立的,不会相互影响

    2、ThreadLocal的基本使用

    (1)常用方法

    (2)ThreadLocal的简单使用

    多线程的不隔离性:

    public class T1 {
        private String content;
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        public static void main(String[] args) {
            T1 t1=new T1();
            for(int  i=0;i<5;i++){
                Thread thread=new Thread(new Runnable() {
                    @Override
                    public void run() {
                        t1.setContent(Thread.currentThread().getName()+"的数据:");
                        System.out.println(Thread.currentThread().getName()+"---"+t1.getContent());
                    }
                });
                thread.setName("线程"+i);
                thread.start();
            }
        }
    }

    测试结果:

    线程1---线程1的数据:
    线程0---线程1的数据:
    线程2---线程2的数据:
    线程3---线程3的数据:
    线程4---线程4的数据:

    将变量与当前线程绑定:

    public class T1 {
        private String content;
        ThreadLocal<String> threadLocal=new ThreadLocal<>();
        public String getContent() {
            return threadLocal.get();
        }
    
        public void setContent(String content) {
            threadLocal.set(content);
        }
    
        public static void main(String[] args) {
            T1 t1=new T1();
            for(int  i=0;i<5;i++){
                Thread thread=new Thread(new Runnable() {
                    @Override
                    public void run() {
                        t1.setContent(Thread.currentThread().getName()+"的数据:");
                        System.out.println(Thread.currentThread().getName()+"---"+t1.getContent());
                    }
                });
                thread.setName("线程"+i);
                thread.start();
            }
        }
    }

    测试结果:

    线程0---线程0的数据:
    线程1---线程1的数据:
    线程2---线程2的数据:
    线程3---线程3的数据:
    线程4---线程4的数据:

    多个线程的数据是相互隔离的。在多线程的场景下,每一个线程的变量都相互独立。例如:线程1设置的变量是变量1,那么获取到的变量也是变量1。

    (3)加锁

    public class T1 {
        private String content;
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
        public static void main(String[] args) {
            T1 t1=new T1();
            for(int  i=0;i<5;i++){
                Thread thread=new Thread(new Runnable() {
                    @Override
                    public void run() {
                        synchronized (T1.class){
                            t1.setContent(Thread.currentThread().getName()+"的数据:");
                            System.out.println(Thread.currentThread().getName()+"---"+t1.getContent());
                        }
                    }
                });
                thread.setName("线程"+i);
                thread.start();
            }
        }
    }

    虽然ThreadLocal模式与synchronized关键字都用于处理多线程并梭访问变量的问题,不过两者处理问题的角度和思路不同。

     用ThreadLocal可以使得程序有更好的性能,因为ThreadLocal没有加锁

    (4)案例

    在银行转账的案例中:

    传统解决方案:

    保证service层和dao层的连接对象的一致,可以通过将service层的参数传递到dao层,但是会提高代码的耦合度

    需要保证每一个线程的连接对象前后一致,也就是说线程1的连接对象对应连接1,线程2的连接对象对应连接2,可以通过加锁(synchronized)的方式保证线程的隔离,但是会降低程序的性能

    ThreadLocal方式:

    传递数据︰保存每个线程绑定的数据,在需要的地方可以直接获取,避免参数直接传递带来的代码耦合问题
    线程隔离︰各线程之间的数据相互隔离却又具备并发性,避兔同步方式带来的性能损失

     

    每个人都会有一段异常艰难的时光 。 生活的压力 , 工作的失意 , 学业的压力。 爱的惶惶不可终日。 挺过来的 ,人生就会豁然开朗。 挺不过来的 ,时间也会教你 ,怎么与它们握手言和 ,所以不必害怕的。 ——杨绛
  • 相关阅读:
    完美世界笔试(动态规划,背包问题)
    腾讯笔试3
    腾讯笔试2
    腾讯笔试1
    阿里笔试1
    Merge Sorted Array
    Partition List
    Reverse Linked List II
    Remove Duplicates from Sorted List II
    白菜刷LeetCode记-704. Binary Search
  • 原文地址:https://www.cnblogs.com/zhai1997/p/13642115.html
Copyright © 2020-2023  润新知