I have some questions regarding the usage and significance of the synchronized
keyword.
- What is the significance of the
synchronized
keyword? - When should methods be
synchronized
? - What does it mean programmatically and logically?
I have some questions regarding the usage and significance of the synchronized
keyword.
synchronized
keyword?synchronized
?
What the other answers are missing is one important aspect: memory barriers. Thread synchronization basically consists of two parts: serialization and visibility. I advise everyone to google for "jvm memory barrier", as it is a non-trivial and extremely important topic (if you modify shared data accessed by multiple threads). Having done that, I advise looking at java.util.concurrent package's classes that help to avoid using explicit synchronization, which in turn helps keeping programs simple and efficient, maybe even preventing deadlocks.
One such example is ConcurrentLinkedDeque. Together with the command pattern it allows to create highly efficient worker threads by stuffing the commands into the concurrent queue -- no explicit synchronization needed, no deadlocks possible, no explicit sleep() necessary, just poll the queue by calling take().
In short: "memory synchronization" happens implicitly when you start a thread, a thread ends, you read a volatile variable, you unlock a monitor (leave a synchronized block/function) etc. This "synchronization" affects (in a sense "flushes") all writes done before that particular action. In the case of the aforementioned ConcurrentLinkedDeque, the documentation "says":
This implicit behavior is a somewhat pernicious aspect because most Java programmers without much experience will just take a lot as given because of it. And then suddenly stumble over this thread after Java isn't doing what it is "supposed" to do in production where there is a different work load -- and it's pretty hard to test concurrency issues.
Here is an explanation from The Java Tutorials.
Consider the following code:
Synchronized normal method
equivalent toSynchronized statement
(use this)Synchronized static method
equivalent toSynchronized statement
(use class)Synchronized statement (using variable)
For
synchronized
, we have bothSynchronized Methods
andSynchronized Statements
. However,Synchronized Methods
is similar toSynchronized Statements
so we just need to understandSynchronized Statements
.=> Basically, we will have
Here is 2 think that help understanding
synchronized
intrinsic lock
associated with it.synchronized statement
, it automatically acquires theintrinsic lock
for thatsynchronized statement's
object and releases it when the method returns. As long as a thread owns anintrinsic lock
, NO other thread can acquire the SAME lock => thread safe.=> When a
thread A
invokessynchronized(this){// code 1}
=> all the block code (inside class) where havesynchronized(this)
and allsynchronized normal method
(inside class) is locked because SAME lock. It will execute afterthread A
unlock ("// code 1" finished).This behavior is similar to
synchronized(a variable){// code 1}
orsynchronized(class)
.SAME LOCK => lock (not depend on which method? or which statements?)
Use synchronized method or synchronized statements?
I prefer
synchronized statements
because it is more extendable. Example, in future, you only need synchronized a part of method. Example, you have 2 synchronized method and it don't have any relevant to each other, however when a thread run a method, it will block the other method (it can prevent by usesynchronized(a variable)
).However, apply synchronized method is simple and the code look simple. For some class, there only 1 synchronized method, or all synchronized methods in the class in relevant to each other => we can use
synchronized method
to make code shorter and easy to understandNote
(it not relevant to much to
synchronized
, it is the different between object and class or none-static and static).synchronized
or normal method orsynchronized(this)
orsynchronized(non-static variable)
it will synchronized base on each object instance.synchronized
or static method orsynchronized(class)
orsynchronized(static variable)
it will synchronized base on classReference
https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
Hope it help
Synchronized simply means that multiple threads if associated with single object can prevent dirty read and write if synchronized block is used on particular object. To give you more clarity , lets take an example :
We've created two MyRunnable class objects , runnable1 being shared with thread 1 and thread 3 & runnable2 being shared with thread 2 only. Now when t1 and t3 starts without synchronized being used , PFB output which suggest that both threads 1 and 3 simultaneously affecting var value where for thread 2 , var has its own memory.
Using Synchronzied, thread 3 waiting for thread 1 to complete in all scenarios. There are two locks acquired , one on runnable1 shared by thread 1 and thread 3 and another on runnable2 shared by thread 2 only.
Threads communicate primarily by sharing access to fields and the objects reference fields refer to. This form of communication is extremely efficient, but makes two kinds of errors possible: thread interference and memory consistency errors. The tool needed to prevent these errors is synchronization.
Synchronized blocks or methods prevents thread interference and make sure that data is consistent. At any point of time, only one thread can access a synchronized block or method (critical section) by acquiring a lock. Other thread(s) will wait for release of lock to access critical section.
Methods are synchronized when you add
synchronized
to method definition or declaration. You can also synchronize a particular block of code with-in a method.It means that only one thread can access critical section by acquiring a lock. Unless this thread release this lock, all other thread(s) will have to wait to acquire a lock. They don't have access to enter critical section with out acquiring lock.
This can't be done with a magic. It's programmer responsibility to identify critical section(s) in application and guard it accordingly. Java provides a framework to guard your application, but where and what all sections to be guarded is the responsibility of programmer.
More details from java documentation page
Intrinsic Locks and Synchronization:
Every object has an intrinsic lock associated with it. By convention, a thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them.
A thread is said to own the intrinsic lock between the time it has acquired the lock and released the lock. As long as a thread owns an intrinsic lock, no other thread can acquire the same lock. The other thread will block when it attempts to acquire the lock.
Making methods synchronized has two effects:
When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
This guarantees that changes to the state of the object are visible to all threads.
Look for other alternatives to synchronization in :
Avoid synchronized(this) in Java?
Think of it as a kind of turnstile like you might find at a football ground. There are parallel steams of people wanting to get in but at the turnstile they are 'synchronised'. Only one person at a time can get through. All those wanting to get through will do, but they may have to wait until they can go through.