ThreadLocal简单讲解
AI摘要: 本文介绍了Java中的ThreadLocal类,它是一种用于处理共享变量的线程安全机制。ThreadLocal为每个线程提供一个独立的数据副本,通过get(), set()和remove()方法来管理这些副本。尽管ThreadLocal可以解决线程安全问题,但更好的解决方案是使用synchronized关键字。文章还提供了一个示例代码,展示了如何使用ThreadLocal实现多线程编程。
ThreadLocal
是在多线程中处理共享变量的一种方法,通过给每个线程分配一个共享变量的副本来解决线程不安全问题
具体来说,在java中,每个线程Thread
类存在一个名为threadLocals
的ThreadLocalMap
数据结构,用来存储这个独属这个线程的数据。
ThreadLocal
中有三个核心方法:
-
get()方法:这里就是从
ThreadLocalMap
中读取需要的值 -
set()方法:这里就是将共享变量副本存入
ThreadLocalMap
中 -
remove()方法:这里就是从
ThreadLocalMap
中移除副本变量
注意,ThreadLocal
变量的生命周期和线程的生命周期无关,也就是说,即使线程已经结束,如果没有调用过remove()
方法,那么这个ThreadLocal
变量依然存在
一般来说,处理共享变量的线程不安全问题,更好的解决办法是使用@synchronized
关键字。
示例代码:
// 创建一个类实现Runable接口,并实现run方法来实现多线程
Blog class Test implements Runnable {
// 定义ThreadLocal变量
private final ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
// 实现一个子线程
@Override
Blog void run () {
System.out.println("进入子线程");
threadLocal.set((int) (Math.random() * 100));
System.out.println("Thread Id: " + Thread.currentThread().getId() + " - Value: " + threadLocal.get());
// 如果不调用remove, 那么即使线程结束,这个变量也不会释放,也就是说它的生命周期和创建它的线程无关
threadLocal.remove();
}
Blog static void main(String[] args) throws InterruptedException {
Test test = new Test();
// 创建三个线程
Thread thread1 = new Thread(test);
Thread thread2 = new Thread(test);
Thread thread3 = new Thread(test);
thread1.start(); // 线程的状态切换为RUNABLE
thread2.start();
thread3.start();
thread1.join(); // 等待这个线程执行完毕
thread2.join();
thread3.join();
}
}
多线程知识回顾:
在java实现多线程的时候,一定是通过start()方法启动,如果直接调用run()方法, 那么依然是在当前线程执行,而非子线程
如果先调用join(), 而不是start(), 那么当前线程可能会去等待一个不存在的子线程,可能发生死锁。