ThreadLocal意为线程本地变量,每个线程的某个变量值可能不一样,将其定义为ThreadLocal变量可将其进行隔离。直接上例子:
- Student.java
public class Student {
private String name;
public void setName(int index) {
this.name = "student" + index;
}
public String getName() {
return this.name;
}
}
注意实例变量name和set方法。
- 定义5个线程对同一个Student变量的name进行修改。
@Test
public void testThreadLocal() throws InterruptedException {
Student student = new Student();
for (int i = 0; i < 5; i++) {
int finalI = i;
new Thread(() -> {
student.setName(finalI);
try {
TimeUnit.SECONDS.sleep(1); // 休眠1秒给其它的线程并行执行的机会,给其它线程设置name的机会
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(student.getName());
}).start();
}
Thread.sleep(3000); // 主线程休眠一个相对长的时间等待5个子线程将结果打印完成
}
执行结果:
student4
student4
student4
student4
student4
发现各个线程的name都一样,线程的name变量被其它线程的修改覆盖了,这时候ThreadLocal的场景就来了,将name变量定义为ThreadLocal变量,每个线程有自己的一份name变量,和其它线程隔离。
- 将Student.java代码进行如下更改:
public class Student {
private ThreadLocal<String> name = new ThreadLocal<>();
public void setName(int index) {
this.name.set("name" + index);
}
public String getName() {
return this.name.get();
}
}
输出结果:
name1
name0
name4
name2
name3
与预期相符。