Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ? For example, instance of Counter will be shared among many threads and each thread can access Counter's public methods. In the below code volatile is used for getter and synchronized is used for 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 ?

like image 805
Karthik Avatar asked Jul 27 '12 04:07

Karthik


People also ask

Should I use volatile with synchronized?

When to use Volatile over Synchronized modifiers can be summed up into this: Use Volatile when you variables are going to get read by multiple threads, but written to by only one thread. Use Synchronized when your variables will get read and written to by multiple threads.

What is synchronized performance?

Synchronization is a computation-intensive and memory-intensive process. You can improve performance by allocating sufficient resources, restructuring the rule project, and reduce data transfer. Allocate sufficient resources. Ensure that your system has enough resources.

Do we need volatile in synchronized block?

volatile and Thread Synchronization synchronized methods and blocks provide both of the above properties at the cost of application performance. volatile is quite a useful keyword because it can help ensure the visibility aspect of the data change without providing mutual exclusion.

Does synchronization techniques are required for volatile variable?

If there's a single thread that writes to the volatile variable and other threads only read the volatile variable then just using volatile is enough, however, if there's a possibility of multiple threads writing to the volatile variable then “synchronized” would be required to ensure atomic writes to the variable.


2 Answers

Yes, you definitely can. In fact, if you look at the source code of AtomicInteger, it's essentially what they do. AtomicInteger.get simply returns value, which is a volatile int (link). 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. On modern hardware, a CAS can eliminate any mutual exclusion; on older hardware, the JVM will put some sort of mutex around the increment.

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 longs and doubles are not subject to word tearing. So your code would work with a long just as well as an int.

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. 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.

like image 56
yshavit Avatar answered Oct 24 '22 09:10

yshavit


1. I have personally used this mechanism of volatile combined with 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.

3. This is because volatile keyword is not a synchronization primitive. 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.

5. And using both volatile and synchronized will do this....

volatile - will reflect the changed values to thread, and prevent caching,

synchronized - But using synchronized keyword, will make sure that only one thread gets the access to the synchronized methods of the class.

like image 27
Kumar Vivek Mitra Avatar answered Oct 24 '22 11:10

Kumar Vivek Mitra