zoukankan      html  css  js  c++  java
  • 关于ThreadLocal的那些事

    这篇文章(看完了再看下面的)很好地解释了ThreadLocal是什么,怎么用,是否能解决线程安全问题,非常nice。但个人认为讲解存在遗漏,进行如下示例补充:

    • InheritableThreadLocal
    public class ThreadIdService {
        private static ThreadLocal<User> localUser=new InheritableThreadLocal<>();
        public static void main(String[] args) {
            User user = new User();
            user.setName("main");
            localUser.set(user);
            System.out.println("main threadUser:"+localUser.get());
            Thread t1 = new Thread() {
                @Override
                public void run() {
                    System.out.println("t1User:"+localUser.get());
                    localUser.get().setName("1");
                    System.out.println("t1User:"+localUser.get());
                }
            };
            Thread t2 = new Thread() {
                @Override
                public void run() {
                    User user2 = new User();
                    user2.setName("2");
                    localUser.set(user2);
                    System.out.println("t2User:"+localUser.get());
                }
            };
            t1.start();
            t2.start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("main threadUser:" + localUser.get());
            user.setName("main2");
        }
    }

    • ThreadLocal
    public class ThreadIdService {
        private static ThreadLocal<User> localUser=new ThreadLocal<>();
        public static void main(String[] args) {
            User user = new User();
            user.setName("main");
            localUser.set(user);
            System.out.println("main threadUser:"+localUser.get());
            Thread t1 = new Thread() {
                @Override
                public void run() {
                    System.out.println("t1User:"+localUser.get());
                    /*localUser.get().setName("1");
                    System.out.println("t1User:"+localUser.get());*/
                }
            };
            Thread t2 = new Thread() {
                @Override
                public void run() {
                    User user2 = new User();
                    user2.setName("2");
                    localUser.set(user2);
                    System.out.println("t2User:"+localUser.get());
                }
            };
            t1.start();
            t2.start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("main threadUser:" + localUser.get());
            user.setName("main2");
        }
    }

     

    • 总结:
    1. ThreadLocal能起到线程件变量隔离的作用。
    2. InheritableThreadLocal则未必,若每个线程存放在InheritableThreadLocal的变量都采用new Object()的方式,则各线程间互不影响,否则传递的是引用,牵一发而动全身!!!
    3. InheritableThreadLocal之所以能够完成线程间变量的传递,是在new Thread()的时候对inheritableThreadLocals对像里的值进行了复制。
    4. 子线程通过继承得到的InheritableThreadLocal里的值与父线程里的InheritableThreadLocal的值具有相同的引用,如果父子线程想实现不影响各自的对象,可以重写InheritableThreadLocal的childValue方法。
  • 相关阅读:
    PyTools包罗万象的python工具包
    手撕神经网络实验报告
    数组模拟队列 以及队列的复用(环形队列)
    Sentinel熔断降级
    二维数组与稀疏数组的转换dataStructures
    Sentine熔断降级进阶
    Centos7防火墙以及端口控制
    docker的安装以及使用命令
    ToDesk个人免费 极致流畅的远程协助软件
    typora+PicGo+gitee搭建免费的的床
  • 原文地址:https://www.cnblogs.com/jixiegongdi/p/13589842.html
Copyright © 2011-2022 走看看