[英]volatile synchronized combination for performance
When Synchronization is used there is a performance impact. 使用同步时会对性能产生影响。 Can volatile be used in combination with synchronized to reduce the performance overhead ?
volatile可以与synchronized结合使用以降低性能开销吗? For example, instance of Counter will be shared among many threads and each thread can access Counter's public methods.
例如,Counter的实例将在许多线程之间共享,每个线程都可以访问Counter的公共方法。 In the below code volatile is used for getter and synchronized is used for setter
在下面的代码中,volatile用于getter,synchronized用于setter
public class Counter
{
private volatile int count;
public Counter()
{
count = 0;
}
public int getCount()
{
return count;
}
public synchronized void increment()
{
++count;
}
}
Please let me know in which scenario this might break ? 请告诉我这可能会破坏的情况?
Yes, you definitely can. 是的,你绝对可以。 In fact, if you look at the source code of
AtomicInteger
, it's essentially what they do. 事实上,如果你看一下
AtomicInteger
的源代码,它基本上就是他们所做的。 AtomicInteger.get
simply returns value
, which is a volatile int
( link ). AtomicInteger.get
只返回value
,这是一个volatile int
( 链接 )。 The only real difference from what you've done and what they do is that they use a CAS for the increment instead of synchronization. 与你所做的和他们做的唯一真正的区别是他们使用CAS来增加而不是同步。 On modern hardware, a CAS can eliminate any mutual exclusion;
在现代硬件上,CAS可以消除任何互斥; on older hardware, the JVM will put some sort of mutex around the increment.
在较旧的硬件上,JVM会在增量周围放置某种互斥。
Volatile reads are about as fast as non-volatile ones, so the reads will be quite fast. 易失性读取速度与非易失性读取速度一样快,因此读取速度非常快。
Not only that, but volatile
fields are guaranteed not to tear: see JLS 17.7 , which specifies that volatile
long
s and double
s are not subject to word tearing. 不仅如此,保证不会撕裂
volatile
区域:参见JLS 17.7 ,它规定了volatile
long
s和double
s不会受到撕裂。 So your code would work with a long
just as well as an int
. 所以你的代码可以使用
long
和int
一样long
。
As Diego Frehner points out, you might not see the result of an increment if you get the value "right as" the increment happens -- you'll either see the before or the after. 正如迭戈弗雷纳所指出的那样,如果你得到增量发生的“正确”值,你可能看不到增量的结果 - 你会看到之前或之后。 Of course, if
get
were synchronized you'd have exactly the same behavior from the read thread -- you'd either see the before-increment or post-increment value. 当然,如果
get
是同步的,那么你从read线程中获得完全相同的行为 - 你要么看到前递增值或后递增值。 So it's really the same either way. 所以这两种方式都是一样的。 In other words, it doesn't make sense to say that you won't see the value as it's happening -- unless you meant word tearing, which (a) you won't get and (b) you would never want.
换句话说,说你不会看到正在发生的价值是没有意义的 - 除非你的意思是撕裂,(a)你不会得到和(b)你永远不会想要的。
1. I have personally used this mechanism of volatile
combined with synchronized
. 1.我曾亲自使用的这种机制
volatile
联合 synchronized
。
2. You can alone use synchronized
, and you will always get a consistent result, but using only volatile
alone will Not yield the same result always. 2.您可以单独使用
synchronized
,并且您将始终获得一致的结果,但仅使用 volatile
不会始终产生相同的结果。
3. This is because volatile keyword is not a synchronization primitive. 3.这是因为挥发性关键字不是原始的同步。 It merely prevents caching of the value on the thread , but it does not prevent two threads from modifying the same value and writing it back concurrently.
它只是防止在线程上缓存值 ,但它不会阻止两个线程修改相同的值并同时将其写回。
4. volatile
give concurrent access to threads without lock , but then using synchronized
will allow only one thread to get access to this and all the synchronized methods in the class. 4.
volatile
给予没有锁的线程的并发访问 ,但是然后使用synchronized
将只允许一个线程访问该类以及类中的所有同步方法。
5. And using both volatile and synchronized
will do this.... 5. 使用
volatile and synchronized
都会这样做....
volatile
- will reflect the changed values to thread, and prevent caching, volatile
-将更改的值反映到线程,并防止缓存,
synchronized
- But using synchronized keyword, will make sure that only one thread gets the access to the synchronized methods of the class. synchronized
-但是使用synchronized关键字,将确保只有一个线程可以访问类的同步方法。
You will not always get the most actual count when calling getCount(). 调用getCount()时,您不会总是获得最实际的计数。 An AtomicInteger could be appropriate for you.
AtomicInteger可能适合您。
There wouldn't be a performance gain from using both. 使用两者都不会带来性能提升。 Volatile guarantees that the value of a variable will be consistent when reading/writing to the variable across threads executing in parallel by preventing caching.
Volatile保证在通过防止缓存并行执行的线程读取/写入变量时变量的值是一致的。 Synchronized , when applied to a method (as you do in your example), only allows a single thread to enter that method at a time and blocks others until execution is complete.
同步 ,当应用于方法时(如您的示例中所做),仅允许单个线程一次输入该方法并阻止其他方法,直到执行完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.