多线程环境中即然共用资源这么困难,那么就干脆不要共用,何不为每个执行绪创造一个资源的复本,将每一个执行绪存取资料的行为加以隔离。
Thread Specific Storage模式通过不共享变量实现了线程安全,并由此自然地避免了与锁的消耗及与之有关的问题。
Thread Specific Storage模式的基础是为每个线程“装备”一个线程特有存储(Thread Specific Storage)。线程特有存储可以理解为一个Map。该Map存放了若干个条目(Entry)。每个条目中的值(Value)为一个线程特有对象,键(Key)为ThreadLocal对象。
1. ThreadLocal的使用示例
定义了两个ThreadLocal类型的变量,线程t1设置的值,对于线程t2是不可见的。
public class ThreadLocalTest1 {
private static ThreadLocal<String> thl1 = new ThreadLocal<>();
private static ThreadLocal<Integer> thl2 = new ThreadLocal<>();
public static void main(String[] args) {
Thread t1 = new Thread(()->{
thl1.set("abc");
thl2.set(12);
thl1.remove();
thl2.remove();
System.out.println(thl1.get()+","+ thl2.get());
});
Thread t2 = new Thread(()->{
System.out.println(thl1.get()+","+ thl2.get());
});
t1.start();
t2.start();
}
}
运行结果:

2. ThreadLocal的使用场景
2.1 线程隔离的数据库连接与事务
定义一个数据库连接,每个线程拿到的数据库连接都是本线程对应的数据库连接。
public class ConnectionManager {
private static final ThreadLocal<Connection> dbConnectionLocal = new ThreadLocal<Connection>() {
@Override
//初始化数据。
//延迟调用方法,在线程第一次调用get或set时才执行,并且只执行1次。默认返回null。
protected Connection initialValue() {
try {
return DriverManager.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
};
public Connection getConnection() {
return dbConnectionLocal.get();
}
}
2.2 线程隔离的session会话
在每个线程session会话都是本线程对应的session。
private static final ThreadLocal threadSession = new ThreadLocal();
public static Session getSession() {
Session s = (Session) threadSession.get();
try {
if (s == null) {
s = getSessionFactory().openSession();
threadSession.set(s);
}
} catch (Exception ex) {
}
return s;
}
总结
具体可以参考《JAVA多线程基础篇 8、线程隔离与ThreadLocal》
多线程系列在github上有一个开源项目,主要是本系列博客的实验代码。
https://github.com/forestnlp/concurrentlab
如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。
您的支持是对我最大的鼓励。
Java多线程:ThreadLocal实战与应用场景解析
本文详细介绍了Java中的ThreadLocal,通过示例展示了如何使用ThreadLocal实现线程间的变量隔离。ThreadLocal常用于创建线程特有的数据库连接和session会话,确保线程安全。此外,还提供了开源项目链接供读者深入学习。

被折叠的 条评论
为什么被折叠?



