[英]volatile vs threadLocal in java
Lets take SimpleDateFormat as an example since it is not thread safe. 让我们以SimpleDateFormat为例,因为它不是线程安全的。
I could allow each thread to have its own copy of SimpleDateFormat using threadLocal like this: 我可以允许每个线程使用threadLocal拥有自己的SimpleDateFormat副本,如下所示:
private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("yyyyMMdd HHmm");
}
};
But the volatile keyword guarantees that a thread will have the most recent copy of the variable. 但volatile关键字保证线程将拥有该变量的最新副本。 So could i not do this instead:
所以我不能这样做:
volatile SimpleDateFormat myformatter;
and achieve the same thread safety ? 并实现相同的线程安全?
the volatile keyword guarantees that a thread will have the most recent copy of the variable
volatile关键字保证线程将拥有该变量的最新副本
Of the volatile variable only , not its fields. 只有 volatile变量,而不是它的字段。
Also, volatile
is only useful if you need to change the value of the variable. 此外,
volatile
仅在您需要更改变量值时才有用。 In your use case, final
looks like it would be more appropriate: 在您的用例中,
final
看起来更合适:
private static final SimpleDateFormat format = ...
This also guarantees that you will have the most recent value of the variable - because it can only be assigned its value once, and static final
has guarantees the visibility once the class is fully loaded. 这也保证了你将获得变量的最新值 - 因为它只能被赋值一次,而
static final
在类完全加载后保证了可见性。
But this isn't the reason why SimpleDateFormat
is not thread safe anyway: it has mutable state which it uses to store intermediate values when formatting the date. 但这并不是
SimpleDateFormat
无论如何都不是线程安全的原因:它具有可变状态,用于在格式化日期时存储中间值。
If one thread calls format
while another is also in the format
method for the same SimpleDateFormatter
instance, these intermediate variables get stomped unpredictably, leading to interference between the threads, and hence unpredictable output. 如果一个线程调用
format
而另一个线程也在同一个SimpleDateFormatter
实例的format
方法中,则这些中间变量会不可预测地被踩踏,从而导致线程之间的干扰,从而导致不可预测的输出。
It doesn't matter whether or not the values of these intermediate variables are up-to-date when read/written by another thread - their updating can be interspersed. 在由另一个线程读取/写入时,这些中间变量的值是否是最新的并不重要 - 它们的更新可以散布。
In short, volatile
doesn't prevent thread interference, and so is not an appropriate alternative to a ThreadLocal
here. 简而言之,
volatile
不会阻止线程干扰,因此这里不是ThreadLocal
的合适替代品。
ThreadLocal
is a facility which enables threads to have their own local copy of an object. ThreadLocal
是一种工具,它使线程拥有自己的对象本地副本。 ThreadLocals are best used with objects that can be thread safe within a thread safety policy of thread confinement (even for many objects that are not "thread safe", thread safe usage is still possible as long as no reference to them leaks out from the confining thread). ThreadLocals最适用于在线程限制的线程安全策略中可以线程安全的对象(即使对于许多不是“线程安全”的对象,只要没有对它们的引用从限制中泄漏,线程安全使用仍然是可能的线)。 ThreadLocals can not help with thread safe usage for mutable objects that are shared outside the thread that instantiates them.
ThreadLocals无法帮助在实例化它们的线程之外共享的可变对象的线程安全使用。
The volatile
keyword is used to provide a weak form of thread safety with a variable that may accessed by many different threads. volatile
关键字用于通过可由许多不同线程访问的变量提供弱形式的线程安全性。 A key difference is that ThreadLocals are most typically not accessed by more than one thread. 一个关键的区别是ThreadLocals通常不被多个线程访问。
Broadly speaking, thread safety requires both visibility (the most recent updates to the variable should be visible to other threads) and mutual exclusion (state transitions must be atomic so that state can not be observed to be inconsistent). 从广义上讲,线程安全需要可见性(变量的最新更新应该对其他线程可见)和互斥(状态转换必须是原子的,以便不能观察到状态不一致)。
Volatile
works with the Java Memory Model to guarantee that the variable will be visible, but it provides no form of mutual exclusion and therefore does not provide atomicity to state transitions in objects. Volatile
与Java Memory Model一起使用以保证变量可见,但它不提供任何形式的互斥,因此不会为对象中的状态转换提供原子性。
Because volatile
and ThreadLocal
are so different, there really is no common circumstance in which you'd be able to substitute one for the other. 因为
volatile
和ThreadLocal
是如此不同,所以实际上没有一个常见的情况可以用一个代替另一个。
您没有使用volatile
实现相同的线程安全volatile
因为SimpleDateFormat
相同实例将在不同的线程中使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.