0%

浅析ThreadLocal

参考:https://www.bilibili.com/video/BV1N741127FH?p=8

案例一:不使用 ThreadLocal,造成线程不隔离的场景:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package thread;

import java.util.concurrent.CountDownLatch;

public class ThreadLocalTest {

private String content;

public void set(String content){
this.content = content;
}
private String get(){
return content;
}

public static void main(String[] args) throws InterruptedException {
ThreadLocalTest test = new ThreadLocalTest();
for (int i = 0;i < 6;i++){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
test.set(Thread.currentThread().getName()+"的数据");
System.out.println(Thread.currentThread().getName()+"-->"+test.get());
}
});
thread.setName("线程"+i);
thread.start();
}

}

}


输出:
线程1-->线程1的数据
线程4-->线程4的数据
线程2-->线程1的数据
线程0-->线程4的数据
线程3-->线程1的数据
线程5-->线程5的数据

由上面输出结果可以看到,A 线程获取的值并不一定是它自身设置的值,这就是多线程之间未做隔离导致的问题。

案例二:使用 threadLocal 将变量绑定在当前线程实现线程隔离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package thread;


public class ThreadLocalTest {
// 将变量绑定在当前线程
ThreadLocal<String> threadLocal = new ThreadLocal<>();

private String content;

public void set(String content){
threadLocal.set(content);
}
private String get(){
return threadLocal.get();
}

public static void main(String[] args) throws InterruptedException {
ThreadLocalTest test = new ThreadLocalTest();
for (int i = 0;i < 6;i++){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
test.set(Thread.currentThread().getName()+"的数据");
System.out.println(Thread.currentThread().getName()+"-->"+test.get());
}
});
thread.setName("线程"+i);
thread.start();
}

}

}

输出:
线程3-->线程3的数据
线程0-->线程0的数据
线程5-->线程5的数据
线程1-->线程1的数据
线程4-->线程4的数据
线程2-->线程2的数据

可以看到每个线程取的都是其设置的值。

ThreadLocal 和 synchronized 的区别

共同点:都用于多线程并发访问变量的问题。

|
| synchronize | ThreadLocal |
| — | — | — |
| 原理 | 同步机制采用以时间换空间的方式,只提供了一份变量,让不同的线程排队去访问。 | 采用以空间换时间的方式,为每一个线程都提供了一份变量的副本从而实现同时访问而互相不干扰。 |
| 侧重点 | 多个线程之间访问资源的同步。 | 多线程中让每个线程之间的数据相互隔离。 |

ThreadLocal 设计

image.png