Volatile and synchronized keywords in Java [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between volatile and synchronized in JAVA (j2me)
I am a bit confused with the 2 java keywords synchronized and volatile.
To what i understand, since java is a multi-threaded language, and by using the keyword synchronized will force it to be executed in 1 thread. Am i correct ?
And volatile also does the same thing ?

Both volatile and synchronized guarantee visibility, but synchronized also provides atomicity:
if one thread thread reads a volatile variable, it has the guarantee to see the previous writes to that same variable, including if they were done by other threads
synchronized blocks give the same guarantee (provided the write and the read are done holding the same monitor) but also provides atomicity guarantees: all instructions within a synchronized block will look atomic from another thread synchronized on the same lock.

For long and double read and write operation are not atomic.
volatile is a modifier you can put on a variable to make read and write operations atomic (including long and double)
The article Atomic Access got more information about it.
Basically it is for making sure that if one thread changed the value of the variable the rest of the threads will see that change and will not able to read it while its written.

Java multi-threading involves two problems, ensuring that multiple operations can be done consistently, without mixing actions by different threads, and making a change in a variable's value available to threads other than the on doing the change.
In reality, a variable does not naturally exist at a single location in the hardware. There may be copies in the internal state of different threads, or in different hardware caches. Simply assigning to a variable automatically changes its value from the point of view of the thread doing the assignment.
If the variable is marked "volatile" other threads will get the changed value.
"synchronized" also ensures changes become visible. Specifically, any change done in one thread before the end of a synchronized block will be visible to reads done by another thread in a subsequent block synchronized on the same object.
In addition, blocks that are synchronized on the same object are forced to run sequentially, not in parallel. That allows one to do things like adding one to a variable, knowing that its value will not change between reading the old value and writing the new one. It also allows consistent changes to multiple variables.
The best way I know to learn what is needed to write solid concurrent code in Java is to read Java Concurrency in Practice

Essentially, volatile is used to indicate that a variable's value will be modified by different threads.
Synchronized is a keyword whose overall purpose is to only allow one thread at a time into a particular section of code thus allowing us to protect, for example, variables or data from being corrupted by simultaneous modifications from different threads.

It is as complicated as described lengthy in Java Memory Model.

Synchronized means that only one thread can access the method or code block at a given time.
Volatile handles the communication between threads. Here is a nice explanation: http://jeremymanson.blogspot.be/2008/11/what-volatile-means-in-java.html

Volatile keyword will make every thread to read or write as an atomic operation in memory location. If you do not use volatile, that variable may be cached by threads, and threads may be reading/writing cached copy instead of actual copy.

Related

Java Memory Model interaction of synchronization, volatile and (stamped) locks

Is the volatile modifier required when working with locks to guarantee memory visibility?
Trying to fully understand concurrency, memory visibility and execution control I came across several sources saying that variables updated in synchronized blocks do not require the field to be volatile (mostly no sources given and actually one page saying synchronized methods and volatility fields need to be used in conjunction).
When approaching the jls chapter 17.4.5 I found:
Two actions can be ordered by a happens-before relationship. If one action
happens-before another, then the first is visible to and ordered before the second.
Is this the section which says that subsequent synchronized method calls guarding the same variable variable will ensure it to be visible to the second thread? If this is the case does the same hold true for locks since we can also guarantee an order?
On the other hand what happens when suddenly we have write locks allowing 2 threads to access the field. Does the entire construct collapse and threads are never guaranteed to updated their cache even in the event if the variable is unlocked?
In short code
int field; //volatile not needed because we have a definite happens-before relationship
Lock lock;
void update(){
//No matter how many threads access this method they will always have
//the most up to date field value to work with.
lock.lock()
field *= 2;
lock.unlock();
}
From the API documentation for Lock:
https://docs.oracle.com/javase/10/docs/api/java/util/concurrent/locks/Lock.html
All Lock implementations must enforce the same memory synchronization
semantics as provided by the built-in monitor lock, as described in
Chapter 17 of The Java™ Language Specification:
A successful lock operation has the same memory synchronization effects as a successful Lock action.
A successful unlock operation has the same memory synchronization effects as a successful Unlock action.
Unsuccessful locking and unlocking operations, and reentrant
locking/unlocking operations, do not require any memory
synchronization effects.
That's a little unclear imo but the gist of it is that yes, Lock is required to work the same way as a monitor (what the synchronized keyword does) and therefore your example does always make the most recent update of field visible without explicitly using the volatile keyword.
P.S. Get Brian Goetz's Java Concurrency in Practice, it explains all of this stuff in a lot more detail. It's basically the bible of all things concurrency in Java.
...and actually one page saying synchronized methods and volatility fields need to be used in conjunction.
You can distill everything you need to know about memory visibility and synchronized blocks down to one simple rule. That is, whatever thread A does to shared variables and objects before it exits from a synchronized (o) {...} block is guaranteed to become visible to thread B by the time thread B enters a synchronized (o) {...} block for the same object, o.
And, as #markspace already said, any implementation of java.util.concurrent.locks.Lock is required to work in the same way.
Is the volatile modifier required when working with locks to guarantee memory visibility?
volatile variable only guarantees memory visibility but not the atomicity. This is one of the main difference between volatile and the synchronized block in Java. So when you use synchronized blocks, variables do not have to be volatile. But If your variable is volatile and performing any compound actions on that variable, then you need to guard the update to the volatile variable with the lock.
Is this the section which says that subsequent synchronized method calls guarding the same variable will ensure it to be visible to the second thread? If this is the case does the same hold true for locks since we can also guarantee an order?
Yes. Because locks will give you both visibility and atomicity.
On the other hand what happens when suddenly we have write locks allowing 2 threads to access the field. Does the entire construct collapse and threads are never guaranteed to updated their cache even in the event if the variable is unlocked?
If you guarding the update to the variable on the same lock only one thread can work on that variable at any given time. So it guarantees consistency. But If you use different locks every time to guard that variable, then more than one thread will modify the variable state and can potentially make the variable state inconsistent. So, in this case, both visibility and atomicity are guaranteed but still, it can lead to inconsistency.

Volatile keyword - is it the only way to protect a value across threads?

In Java, the volatile keyword is for direct read and write from main memory so that reads or writes won't be lost if multiple threads are accessing a variable.
Without using volatile, is there any other way to achieve this functionality? I came across this question but couldn't figure out a solution.
Basically, if you want to safely access a non-volatile variable from multiple threads, you need to surround all read/write access to the variable with synchronized blocks that use a shared monitor. Read access to volatile variables (in general) need not be synchronized, because each read operation is guaranteed to see the last write to the variable by any thread.
It is important to notice that using volatile fields alone does not eliminate the need for synchronization when you e.g. need to atomically read a value of a variable, followed by a write to the same variable. A common use case for this is incrementing a counter. As #Louis Wasserman suggests, for these purposes, classes in the java.util.concurrent.atomic package provide reliable and easy to use methods, such as compareAndSet(...) and incrementAndGet().
The Java Language Specification describes a set of happens-before relationships, and a set of synchronizes-with actions. If one action synchronizes-with a following action, it happens-before. A write is guaranteed to be visible if happens-before a read, in this technical sense.
Writes performed inside a synchronized block are visible to threads that synchronize on that lock afterwards, because release of a lock synchronizes-with acquisition by another thread.
A write to a volatile variable synchronizes-with subsequent reads of that variable, so it is visible.
A number of the utilities in the java.util.concurrent also provide a happens-before relationship. For example, actions taken by a thread before it calls countDown() on a CountDownLatch are visible to threads that return from a call to await() on that latch. Of course, many of these APIs achieve this by using volatile, synchronized themselves.

Threadsafe vs Synchronized

I'm new to java.
I'm little bit confused between Threadsafe and synchronized.
Thread safe means that a method or class instance can be used by multiple threads at the same time without any problems occurring.
Where as Synchronized means only one thread can operate at single time.
So how they are related to each other?
The definition of thread safety given in Java Concurrency in Practice is:
A class is thread-safe if it behaves correctly when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, and with no additional synchronization or other coordination on the part of the calling code.
For example, a java.text.SimpleDateFormat object has internal mutable state that is modified when a method that parses or formats is called. If multiple threads call the methods of the same dateformat object, there is a chance a thread can modify the state needed by the other threads, with the result that the results obtained by some of the threads may be in error. The possibility of having internal state get corrupted causing bad output makes this class not threadsafe.
There are multiple ways of handling this problem. You can have every place in your application that needs a SimpleDateFormat object instantiate a new one every time it needs one, you can make a ThreadLocal holding a SimpleDateFormat object so that each thread of your program can access its own copy (so each thread only has to create one), you can use an alternative to SimpleDateFormat that doesn't keep state, or you can do locking using synchronized so that only one thread at a time can access the dateFormat object.
Locking is not necessarily the best approach, avoiding shared mutable state is best whenever possible. That's why in Java 8 they introduced a date formatter that doesn't keep mutable state.
The synchronized keyword is one way of restricting access to a method or block of code so that otherwise thread-unsafe data doesn't get corrupted. This keyword protects the method or block by requiring that a thread has to acquire exclusive access to a certain lock (the object instance, if synchronized is on an instance method, or the class instance, if synchronized is on a static method, or the specified lock if using a synchronized block) before it can enter the method or block, while providing memory visibility so that threads don't see stale data.
Thread safety is a desired behavior of the program, where the synchronized block helps you achieve that behavior. ​There are other methods of obtaining Thread safety e.g immutable class/objects. Hope this helps.
Thread safety: A thread safe program protects it's data from memory consistency errors. In a highly multi-threaded program, a thread safe program does not cause any side effects with multiple read/write operations from multiple threads on shared data (objects). Different threads can share and modify object data without consistency errors.
synchronized is one basic method of achieving ThreadSafe code.
Refer to below SE questions for more details:
What does 'synchronized' mean?
You can achieve thread safety by using advanced concurrency API. This documentation page provides good programming constructs to achieve thread safety.
Lock Objects support locking idioms that simplify many concurrent applications.
Concurrent Collections make it easier to manage large collections of data, and can greatly reduce the need for synchronization.
Atomic Variables have features that minimize synchronization and help avoid memory consistency errors.
ThreadLocalRandom (in JDK 7) provides efficient generation of pseudorandom numbers from multiple threads.
Refer to java.util.concurrent and java.util.concurrent.atomic packages too for other programming constructs.
Related SE question:
Synchronization vs Lock
Synchronized: only one thread can operate at same time.
Threadsafe: a method or class instance can be used by multiple threads at the same time without any problems occurring.
If you relate this question as, Why synchronized methods are thread safe? than you can get better idea.
As per the definition this appears to be confusive. But not,if you understand it analytically.
Synchronized means: sequentially one by one in an order,Not concurrently [Not at the same time].
synchronized method not allows to act another thread on it, While a thread is already working on it.This avoids concurrency.
example of synchronization: If you want to buy a movie ticket,and stand in a queue. you will get the ticket only after the person in front of you get the ticket.
Thread safe means: method becomes safe to be accessed by multiple threads without any problem at the same time.synchronized keyword is one of the way to achieve 'thread safe'. But Remember:Actually while multiple threads tries to access synchronized method they follow the order so becomes safe to access. Actually, Even they act at the same time, but cannot access the same resource(method/block) at the same time, because of synchronized behavior of the resource.
Because If a method becomes synchronized, so this is becomes safe to allow multiple threads to act on it, without any problem. Remember:: multiple threads "not act on it at the same time" hence we call synchronized methods thread safe.
Hope this helps to understand.
After patiently reading through a lot of answers and not being too technical at the same time, I could say something definite but close to what Nayak had already replied to fastcodejava above, which comes later on in my answer but look
synchronization is not even close to brute-forcing thread-safety; it's just making a piece of code (or method) safe and incorruptible for a single authorized thread by preventing it from being used by any other threads.
Thread safety is about how all threads accessing a certain element behave and get their desired results in the same way if they would have been sequential (or even not so), without any form of undesired corruption (sorry for the pleonasm) as in an ideal world.
One of the ways of achieving proximity to thread-safety would be using classes in java.util.concurrent.atomic.
Sad, that they don't have final methods though!
Nayak, when we declare a method as synchronized, all other calls to it from other threads are locked and can wait indefinitely. Java also provides other means of locking with Lock objects now.
You can also declare an object to be final or volatile to guarantee its availability to other concurrent threads.
ref: http://www.javamex.com/tutorials/threads/thread_safety.shtml
In practice, performance wise, Thread safe, Synchronised, non-thread safe and non-synchronised classes are ordered as:
Hashtable(slower) < Collections.SynchronizedMap < HashMap(fastest)

Simultaneous reading and changing the variable by different threads

I am interested in the situation where one thread is waiting for change of a variable in the while loop:
while (myFlag == false) {
// do smth
}
It is repeating an infinite number of times.
In the meantime, another thread have changed the value of this variable:
myFlag = true;
Can the reader-thread see the result of changing the value of the variable in the other thread if this variable is NOT volatile? In general, as I understand it will never happen. Or am I wrong? Then when and under what circumstances, the first thread can see the change in the variable and exit the loop? Is this possible without using volatile keyword? Does size of processor's cache play role in this situation?
Please explain and help me understand! Thank you in advance!!
Can the reader-thread see the result of changing the value of the variable in the other thread if this variable is NOT volatile?
It may be able to, yes. It's just that it won't definitely see the change.
In general, as I understand it will never happen.
No, that's not the case.
You're writing to a variable and then reading from it in a different thread. Whether or not you see it will depend on the exact processor and memory architecture involved. Without any memory barriers involved, you aren't guaranteed to see the new value - but you're certainly not guaranteed not to see it either.
Can the reader-thread see the result of changing the value of the variable in the other thread if this variable is NOT volatile?
I'd like to expand a bit on #Jon's excellent answer.
The Java memory model says that all memory in a particular thread will be updated if it crosses any memory barrier. Read barriers cause all cached memory in a particular thread to be updated from central memory and write barriers cause local thread changes to be written to central.
So if your thread that writes to another volatile field or enters a synchronized block it will cause your flag to be updated in central memory. If the reading thread reads from another volatile field or enters a synchronized block in the // do smth section after the update has happened, it will see the update. You just can't rely on when this will happen or if the order of write/read happens appropriately. If your thread doesn't have other memory synchronization points then it may never happen.
Edit:
Given the discussion below, which I've had a couple times now in various different questions, I thought I might expand more on my answer. There is a big difference between the guarantees provided by the Java language and its memory-model and the reality of JVM implementations. The JLS and JMM define memory-barriers and talk about "happens-before" guarantees only between volatile reads and writes on the same field and synchronized locks on the same object.
However, on all architectures that I've heard of, the implementation of the memory barriers that enforce the memory synchronization are not field or object specific. When a read is done on a volatile field and the read-barrier is crossed on a specific thread, it will be updated with all of central memory, not just the particular volatile field in question. This is the same for volatile writes. After a write is made to a volatile field, all updates from the local thread are written to central memory, not just the field. What the JLS does guarantee is that instructions cannot be reordered past the volatile access.
So, if thread-A has written to a volatile field then all updates, even those not marked as volatile will have been written to central memory. After this operation has completed, if thread-B then reads from a different volatile field, he will see all of thread-A's updates, even those not marked as volatile. Again, there is no guarantees around the timing of these events but if they happen in that order then the two threads will be updated.

Synchronized Vs Semaphore

While reading concurrency in Java, I have following doubts:
Does Java provides lower level construct then synchronized for synchronization?
In what circumstances will we use semaphore over synchronized (which provides monitor behaviour in Java)
Synchronized allows only one thread of execution to access the resource at the same time. Semaphore allows up to n (you get to choose n) threads of execution to access the resource at the same time.
There is also volatile keyword, according to http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html volatile variable access is more efficient than accessing these variables through synchronized code
java.util.concurrent.Semaphore is used to restrict the number of threads that can access a resource. That is, while synchronized allows only one thread to aquire lock and execute the synchonized block / method, Semaphore gives permission up to n threads to go and blocks the others.
There is also atomics. This gives access to the basic hardware compare-and-swap command that's the basis of all synchronization. It allows you, for example, to increment a number safely. If you ++ a volatile field, another thread executing the same instruction could read the field before your thread writes to it, then write back to it after your thread. So one increment gets lost. Atomics do the read and write "atomically" and so avoid the problem.
Actually, volatiles, synchronized statements, and atomics tend to force all thread data to be refreshed from main memory and/or written to main memory as appropriate, so none of them are really that low level. (I'm simplifying here. Unlike C#, Java does not really have a concept of "main memory".)

Categories