Java核心技术卷一 14.5.12 线程局部变量

193 篇文章 9 订阅
107 篇文章 0 订阅

前面几节中, 我们讨论了在线程间共享变量的风险。有时可能要避免共享变量, 使用ThreadLocal 辅助类为各个线程提供各自的实例。 例如,SimpleDateFormat 类不是线程安全的。
假设有一个静态变量:

public static final SimpleDateFormat dateFormat = new SimpleDateForniat("yyyy-MM-dd")

如果两个线程都执行以下操作:

String dateStamp = dateFormat.format(new Date());

结果可能很混乱,因为 dateFormat 使用的内部数据结构可能会被并发的访问所破坏。当然可以使用同步,但开销很大; 或者也可以在需要时构造一个局部 SimpleDateFormat 对象,不过这也太浪费了。

要为每个线程构造一个实例,可以使用以下代码:

public static final ThreadLocal<SimpleDateFormat> dateFormat =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));

要访问具体的格式化方法,可以调用:

String dateStamp = dateFormat.get().format(new Date());

在一个给定线程中首次调用 get 时, 会调用 initialValue 方法。在此之后, get 方法会返回属于当前线程的那个实例。

在多个线程中生成随机数也存在类似的问题。java.util.Random 类是线程安全的。但是如果多个线程需要等待一个共享的随机数生成器, 这会很低效。

可以使用 ThreadLocal 辅助类为各个线程提供一个单独的生成器, 不过 Java SE 7 还另外提供了一个便利类。只需要做以下调用:

int random = ThreadLocalRandom.current().nextlnt(upperBound);

ThreadLocalRandom.current() 调用会返回特定于当前线程的 Random 类实例。

参考:
Java核心技术卷一基础知识第10版 14.5.12 线程局部变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值