码迷,mamicode.com
首页 > 其他好文 > 详细

ThreadLocal不安全的情况举例(附代码)

时间:2021-04-22 15:36:52      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:run   rup   变量   http   ide   interrupt   int   lazy   rri   

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

 

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

技术图片

 

ThreadLocal不安全的情况举例(附代码)

标签:run   rup   变量   http   ide   interrupt   int   lazy   rri   

原文地址:https://www.cnblogs.com/mkl34367803/p/14684485.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!