zoukankan      html  css  js  c++  java
  • ThreadLocal不安全的情况举例(附代码)

    ThreadLocal通过Thread.threadlocals保存ThreadLocal的副本,但是ThreadLocal变量在多线程情况下仍然是不安全的。

    class MyClass{
        private Integer value;
        public MyClass(){
        }
        public MyClass(Integer value){
            this.value=value;
        }
    
        public Integer getValue() {
            return value;
        }
    
        public void setValue(Integer value) {
            this.value = value;
        }
    
        @Override
        public String toString() {
            return "MyClass{" +
                    "value=" + value +
                    '}';
        }
    }
    public class ThreadLocalTest {
        static ThreadLocal<MyClass> threadLocal=new ThreadLocal<>();
    
        public static void main(String[] args) {
            MyClass myClass=new MyClass();
            new Thread(){
                @Override
                public void run() {
                    myClass.setValue(10);
                    threadLocal.set(myClass);
                    System.out.println(currentThread().getName()+":"+threadLocal.get());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(currentThread().getName()+":"+threadLocal.get());
                    myClass.setValue(10); //这个值会影响下面线程最后一次打印
                }
            }.start();
    
    
            new Thread(){
                @Override
                public void run() {
                    myClass.setValue(20);
                    threadLocal.set(myClass);
                    System.out.println(currentThread().getName()+":"+threadLocal.get());
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(currentThread().getName()+":"+threadLocal.get());
    
                }
            }.start();
        }
    }

    通过查看上面代码的执行结果,可以看到,两个线程对myClass的value设置后,相互影响,线程逻辑完全混乱了,并不是我们想象中的各自拥有变量副本。

    正确的写法是多线程共享ThreadLocal变量,但是不共享ThreadLocal里面的变量。也就是每个线程共享Thread.threadLocals的key,而不不共享Thread.threadLocals的value。

    public class ThreadLocalTest111 {
        static ThreadLocal<MyClass> threadLocal=new ThreadLocal<>();
    
        public static void main(String[] args) {
            new Thread(){
                @Override
                public void run() {
                    MyClass myClass=new MyClass(10);
                    threadLocal.set(myClass);
                    System.out.println(currentThread().getName()+":"+threadLocal.get());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(currentThread().getName()+":"+threadLocal.get());
                    myClass.setValue(10); //这个值会影响下面线程最后一次打印
                }
            }.start();
    
    
            new Thread(){
                @Override
                public void run() {
                    MyClass myClass=new MyClass(20);
                    threadLocal.set(myClass);
                    System.out.println(currentThread().getName()+":"+threadLocal.get());
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(currentThread().getName()+":"+threadLocal.get());
    
                }
            }.start();
        }
    }

    上面这个代码就是线程安全了。

  • 相关阅读:
    【转】禁用chrome firefox 的 WebRTC功能防止真实IP泄漏
    这是我的主场
    【转】反编译获取任何微信小程序源码(完)
    【转】npm 安装express npm ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE
    查询最新的邮编地区
    【转】汇编语言入门教程
    Microsoft Windows远程桌面协议中间人攻击漏洞(CVE-2005-1794)漏洞解决方案(Windows server2003)
    IIS隐藏版本号教程(Windows Server 2003)
    Windows Server 2003添加防火墙策略教程
    Tomcat禁用SSLv3和RC4算法
  • 原文地址:https://www.cnblogs.com/mkl34367803/p/14684485.html
Copyright © 2011-2022 走看看