• 关于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方法。
  • 相关阅读:
    Eclipse编辑properties文件中文乱码
    Spark安装
    安装VirtualBox后,VMware不能上网
    Hadoop Eclipse插件编译
    MapReduce 常见问题
    MapReduce 气象数据集
    Maven构建Hadoop开发环境
    Eclipse安装Maven
    吴恩达深度学习笔记 course4 week2 深度卷积网络 实例探究
    吴恩达深度学习笔记 cousrse4 week1作业
  • 原文地址:https://www.cnblogs.com/jixiegongdi/p/13589842.html
Copyright © 2020-2023  润新知