Java并发07-ThreadLocal

本文探讨了在线程间共享变量的风险,推荐使用ThreadLocal为每个线程提供独立的SimpleDateFormat实例,以避免同步开销。同时介绍了ThreadLocalRandom在并发环境下的优势,它减少了多线程对同一Random实例的竞争,提高了性能。通过示例展示了如何从Math.random()切换到ThreadLocalRandom,以实现更高效的并发随机数生成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在线程之间共享变量是存在风险的,有时可能要避免共享变量,使用ThreadLocal辅助类为各个线程提供各自的实例。
例如有一个静态变量

public static final SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd”);
如果两个线程同时调用sdf.format(…)
那么可能会很混乱,因为sdf使用的内部数据结构可能会被并发的访问所破坏。当然可以使用线程同步,但是开销很大;或者也可以在需要时构造一个局部SImpleDateFormat对象。但这很浪费

要为每一个线程构造一个对象
使用ThreadLocal
API:
在这里插入图片描述

public static final ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<SimpleDateFormat>() {

		@Override
		protected SimpleDateFormat initialValue() {
			return new SimpleDateFormat("yyyy-MM-dd");
		}
	};

将其作为成员变量。在一个给定线程中首次调用get方法,会调用initValue方法
在此之后,get方法会返回属于当前线程的那个实例

Java.util.Random类是线程安全的,但是同样最好是每个线程都拥有一个这个对象的副本
可以使用ThreadLocalRandom类
ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。ThreadLocalRandom不是直接用new实例化,而是第一次使用其静态方法current()。

从Math.random()改变到ThreadLocalRandom有如下好处:

我们不再有从多个线程访问同一个随机数生成器实例的争夺。
取代以前每个随机变量实例化一个随机数生成器实例,我们可以每个线程实例化一个。

代码改变如下:

// double u = r.nextDouble();
double u = ThreadLocalRandom.current().nextDouble();

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值