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方法。
  • 相关阅读:
    Understanding about Baire Category Theorem
    Isometric embedding of metric space
    Convergence theorems for measurable functions
    Mindmap for "Principles of boundary element methods"
    Various formulations of Maxwell equations
    Existence and uniqueness theorems for variational problems
    Kernels and image sets for an operator and its dual
    [loj6498]农民
    [luogu3781]切树游戏
    [atAGC051B]Three Coins
  • 原文地址:https://www.cnblogs.com/jixiegongdi/p/13589842.html
Copyright © 2011-2022 走看看