j2e*_*nue 6 java multithreading volatile thread-local
让我们以SimpleDateFormat为例,因为它不是线程安全的.
我可以允许每个线程使用threadLocal拥有自己的SimpleDateFormat副本,如下所示:
private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("yyyyMMdd HHmm");
}
};
Run Code Online (Sandbox Code Playgroud)
但volatile关键字保证线程将拥有该变量的最新副本.所以我不能这样做:
volatile SimpleDateFormat myformatter;
Run Code Online (Sandbox Code Playgroud)
并实现相同的线程安全?
volatile 关键字保证线程将拥有变量的最新副本
仅volatile 变量,而不是其字段。
此外,volatile仅当您需要更改变量的值时才有用。在您的用例中,final看起来更合适:
private static final SimpleDateFormat format = ...
Run Code Online (Sandbox Code Playgroud)
这也保证您将拥有变量的最新值 - 因为它只能被分配一次其值,并且static final一旦类完全加载就保证可见性。
但这SimpleDateFormat并不是线程安全的原因:它具有可变状态,用于在格式化日期时存储中间值。
如果一个线程调用format而另一个线程也在format同一个SimpleDateFormatter实例的方法中,这些中间变量会被不可预测地踩踏,导致线程之间的干扰,从而导致不可预测的输出。
当被另一个线程读/写时,这些中间变量的值是否是最新的并不重要——它们的更新可以穿插。
简而言之,volatile不会阻止线程干扰,因此不是ThreadLocalhere的合适替代方案。
| 归档时间: |
|
| 查看次数: |
3547 次 |
| 最近记录: |