java 中ThreadLocal 的正确用法
发布时间 - 2026-01-11 00:22:38 点击率:次java 中ThreadLocal 的正确用法

用法一:在关联数据类中创建private static ThreadLocalThreaLocal的JDK文档中说明:ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread。如果我们希望通过某个类将状态(例如用户ID、事务ID)与线程关联起来,那么通常在这个类中定义private static类型的ThreadLocal 实例。
例如,在下面的类中,私有静态 ThreadLocal 实例(serialNum)为调用该类的静态 SerialNum.get() 方法的每个线程维护了一个“序列号”,该方法将返回当前线程的序列号。(线程的序列号是在第一次调用 SerialNum.get() 时分配的,并在后续调用中不会更改。)
public class SerialNum {
// The next serial number to be assigned
private static int nextSerialNum = 0;
private static ThreadLocal serialNum = new ThreadLocal() {
protected synchronized Object initialValue() {
return new Integer(nextSerialNum++);
}
};
public static int get() {
return ((Integer) (serialNum.get())).intValue();
}
}
【例】
public class ThreadContext {
private String userId;
private Long transactionId;
private static ThreadLocal threadLocal = new ThreadLocal(){
@Override
protected ThreadContext initialValue() {
return new ThreadContext();
}
};
public static ThreadContext get() {
return threadLocal.get();
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public Long getTransactionId() {
return transactionId;
}
public void setTransactionId(Long transactionId) {
this.transactionId = transactionId;
}
}
用法二:在Util类中创建ThreadLocal
这是上面用法的扩展,即把ThreadLocal的创建放到工具类中。
【例】例如hibernate的工具类:
public class HibernateUtil {
private static Log log = LogFactory.getLog(HibernateUtil.class);
private static final SessionFactory sessionFactory; //定义SessionFactory
static {
try {
// 通过默认配置文件hibernate.cfg.xml创建SessionFactory
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
log.error("初始化SessionFactory失败!", ex);
throw new ExceptionInInitializerError(ex);
}
}
//创建线程局部变量session,用来保存Hibernate的Session
public static final ThreadLocal session = new ThreadLocal();
/**
* 获取当前线程中的Session
* @return Session
* @throws HibernateException
*/
public static Session currentSession() throws HibernateException {
Session s = (Session) session.get();
// 如果Session还没有打开,则新开一个Session
if (s == null) {
s = sessionFactory.openSession();
session.set(s); //将新开的Session保存到线程局部变量中
}
return s;
}
public static void closeSession() throws HibernateException {
//获取线程局部变量,并强制转换为Session类型
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
}
用法三:在Runnable中创建ThreadLocal
还有一种用法是在线程类内部创建ThreadLocal,基本步骤如下:
1、在多线程的类(如ThreadDemo类)中,创建一个ThreadLocal对象threadXxx,用来保存线程间需要隔离处理的对象xxx。
2、在ThreadDemo类中,创建一个获取要隔离访问的数据的方法getXxx(),在方法中判断,若ThreadLocal对象为null时候,应该new()一个隔离访问类型的对象,并强制转换为要应用的类型。
3、在ThreadDemo类的run()方法中,通过调用getXxx()方法获取要操作的数据,这样可以保证每个线程对应一个数据对象,在任何时刻都操作的是这个对象。
public class ThreadLocalTest implements Runnable{
ThreadLocal<Studen> studenThreadLocal = new ThreadLocal<Studen>();
@Override
public void run() {
String currentThreadName = Thread.currentThread().getName();
System.out.println(currentThreadName + " is running...");
Random random = new Random();
int age = random.nextInt(100);
System.out.println(currentThreadName + " is set age: " + age);
Studen studen = getStudent(); //通过这个方法,为每个线程都独立的new一个student对象,每个线程的的student对象都可以设置不同的值
studen.setAge(age);
System.out.println(currentThreadName + " is first get age: " + studen.getAge());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( currentThreadName + " is second get age: " + studen.getAge());
}
private Studen getStudent() {
Studen studen = studenThreadLocal.get();
if (null == studen) {
studen = new Studen();
studenThreadLocal.set(studen);
}
return studen;
}
public static void main(String[] args) {
ThreadLocalTest t = new ThreadLocalTest();
Thread t1 = new Thread(t,"Thread A");
Thread t2 = new Thread(t,"Thread B");
t1.start();
t2.start();
}
}
class Studen{
int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# java
# ThreadLocal
# 详解及实例
# ThreadLocal使用方法
# 深入解析Java中ThreadLocal线程类的作用和用法
# java线程本地变量ThreadLocal详解
# java ThreadLocal使用案例详解
# Java ThreadLocal用法实例详解
# 详解Java中的ThreadLocal
# java多线程编程之InheritableThreadLocal
# 简单分析Java线程编程中ThreadLocal类的使用
# Java ThreadLocal 线程安全问题解决方案
# 深入理解Java并发编程之ThreadLocal
# 类中
# 是在
# 新开
# 转换为
# 创建一个
# 的是
# 这是
# 还没有
# 在这个
# 并在
# 希望能
# 谢谢大家
# 多线程
# 配置文件
# 即把
# 文档
# Long
# userId
# LogFactory
# br
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在阿里云服务器自主搭建网站?
html5audio标签播放结束怎么触发事件_onended回调方法【教程】
今日头条AI怎样推荐抢票工具_今日头条AI抢票工具推荐算法与筛选【技巧】
Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?
如何在万网自助建站中设置域名及备案?
如何快速重置建站主机并恢复默认配置?
JavaScript中的标签模板是什么_它如何扩展字符串功能
简单实现jsp分页
Laravel怎么判断请求类型_Laravel Request isMethod用法
Thinkphp 中 distinct 的用法解析
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
黑客如何利用漏洞与弱口令入侵网站服务器?
HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】
Laravel如何设置自定义的日志文件名_Laravel根据日期或用户ID生成动态日志【技巧】
Laravel如何生成API文档?(Swagger/OpenAPI教程)
Laravel如何配置任务调度?(Cron Job示例)
LinuxCD持续部署教程_自动发布与回滚机制
Laravel怎么为数据库表字段添加索引以优化查询
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
如何用PHP工具快速搭建高效网站?
阿里云高弹*务器配置方案|支持分布式架构与多节点部署
教你用AI润色文章,让你的文字表达更专业
焦点电影公司作品,电影焦点结局是什么?
怎样使用JSON进行数据交换_它有什么限制
浅述节点的创建及常见功能的实现
Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理
Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
如何在建站宝盒中设置产品搜索功能?
BootStrap整体框架之基础布局组件
如何解决hover在ie6中的兼容性问题
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置
如何用IIS7快速搭建并优化网站站点?
uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址
如何自定义建站之星模板颜色并下载新样式?
Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程
JavaScript如何实现倒计时_时间函数如何精确控制
Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践
香港服务器网站推广:SEO优化与外贸独立站搭建策略
Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解
微信小程序 canvas开发实例及注意事项
如何获取上海专业网站定制建站电话?
用v-html解决Vue.js渲染中html标签不被解析的问题
Python企业级消息系统教程_KafkaRabbitMQ高并发应用
无锡营销型网站制作公司,无锡网选车牌流程?
黑客入侵网站服务器的常见手法有哪些?
如何在腾讯云服务器快速搭建个人网站?
Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康
Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】

