ThreadLocal 和 Thread 局部变量的区别? ThreadLocal 在什么场景下,用它比用 Thread 的局部变量好?

2016-07-21 17:11:49 +08:00
 zhongxigeng

分析:

  1. ThreadLocal :提供线程内的局部变量,这种变量在线程的生命周期内起作用
  2. Thread 局部变量:线程内部的变量

二者有啥区别,怎么看 都觉得 二者一摸一样,请大家分析分析 ThreadLocal 在什么场景下,用它比用 Thread 的局部变量好。

自写的测试代码:

public class ThreadLocalTest {

    private static final ThreadLocal<Integer> value = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Thread(new MyThread(i + "")).start();
        }
    }

    static class MyThread implements Runnable {
        private String index;

        public MyThread(String index) {
            this.index = index;
        }

        //局部变量
        private Integer num = 0;

        public void run() {
            System.out.println("线程" + index + "的初始 num:" + num);
            System.out.println("线程" + index + "的初始 value:" + value.get());
            for (int i = 0; i < 10; i++) {
                num += i;
                value.set(value.get() + i);
            }
            System.out.println("线程" + index + "的累加 num:" + num);
            System.out.println("线程" + index + "的累加 value:" + value.get());
        }
    }
}
5544 次点击
所在节点    Java
8 条回复
zhongxigeng
2016-07-21 17:29:18 +08:00
已自己找到了不同点,问的问题很 2 ,见谅~~
```java
public static void main(String[] args) {

MyThread myThread = new MyThread("oo");
new Thread(myThread,"1").start();
new Thread(myThread,"2").start();
}
static class MyThread implements Runnable {
private String index;

public MyThread(String index) {
this.index = index;
}

//局部变量
private Integer num = 0;

public void run() {
System.out.println("线程" + Thread.currentThread().getName() +index+ "的初始 num:" + num);
System.out.println("线程" + Thread.currentThread().getName()+index + "的初始 value:" + value.get());
for (int i = 0; i < 10; i++) {
num += i;
value.set(value.get() + i);
}
System.out.println("线程" + Thread.currentThread().getName() +index + "的累加 num:" + num);
System.out.println("线程" + Thread.currentThread().getName() +index + "的累加 value:" + value.get());
}
}
```

结果:
```
线程 2oo 的初始 num:0
线程 1oo 的初始 num:0
线程 2oo 的初始 value:0
线程 1oo 的初始 value:0
线程 2oo 的累加 num:45
线程 1oo 的累加 num:90
线程 1oo 的累加 value:45
线程 2oo 的累加 value:45
```

结论:自定义私有局部变量 线程不安全,当上述情况时
8bit
2016-07-21 17:29:54 +08:00
threadlocal 用来处理全局变量的共享问题,局部变量在一定范围内就是线程封闭的呀
aabbccli
2016-07-21 20:01:28 +08:00
你可以把它看作是一个全局的 MAP,KEY 为线程 ID , VALUE 为对应线程设置的值
hinkal
2016-07-21 20:10:55 +08:00
我也思考过这个问题,应用场景区别就是,使用线程局部存储后,可以对所有线程都调用同样的变量名啊
lululau
2016-07-21 20:16:22 +08:00
第二个只是对象的私有实例变量好吗,和线程有啥关系
hinkal
2016-07-21 20:21:31 +08:00
补充,刚才回答以为是 win32API 请自动忽略...
Override
2016-07-21 21:26:36 +08:00
我仿佛又听到有人在背后偷偷 @我
wangyunbin1989
2016-07-22 15:06:49 +08:00
ThreadLocal 类似于一个线程中的全局变量

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/293995

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX