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();
        }
    }

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

  • 相关阅读:
    mdx中nonempty 和 non empty的区别
    shrink log和查询数据库 backup,restore,shrink 进度 和 还原历史 的sql (for sqlserver)re
    方差分析 概述
    从 高斯 到 正态分布 到 Z分布 到 t分布
    数据集市 数据仓库 Immon Kimball模型的概念说明
    【React Native 实战】微信登录
    【React Native 实战】商品分类
    一步步学习PHP笔记(李炎恢瓢城web俱乐部-多用户留言系统)01
    wampserver下打开phpMyAdmin出现403错误的问题解决方法
    windows 支持curl命令
  • 原文地址:https://www.cnblogs.com/mkl34367803/p/14684485.html
Copyright © 2011-2022 走看看