A Java synchronized block marks a method or block of code as synchronized. A synchronized block in Java can only be executed by a single thread at a time (depending on how you use it). Java synchronized blocks can be used to avoid race conditions.
# Java Concurrency Utilities
The `synchronized` mechanism was Java's first mechanism for synchronizing access to objects shared by multiple threads. The `synchronized` mechanism isn't very advanced though. That is why Java 5 got a whole set of concurrency utilities classes to help developers implement more fine grained concurrency control than what you get with `synchronized`.
# The Java Synchronized Keyword
A synchronized block in Java is synchronized on some object. All synchronized blocks synchronized on the same object can only have one thread executing inside them at the same time. All other threads attempting to enter the synchronized block are blocked until the thread inside the synchronized block exits the block.
The `synchronized` keyword can be used to mark four different types of blocks:
* Instance methods
* Static methods
* Code blocks inside instance methods
* Code blocks inside static methods
## Synchronized Instance Methods
A synchronized instance method in Java is synchronized on the instance (object) owning the method. Thus, each instance has its synchronized methods synchronized on a different object: the owning instance.
Only one thread per instance can execute inside a synchronized instance method. If more than one instance exist, then one thread at a time can execute inside a synchronized instance method per instance. One thread per instance.
This is true across all synchronized instance methods for the same object (instance). Thus, in the following example, only one thread can execute inside either of of the two synchronized methods. One thread in total per instance:
```
public class MyCounter {
private int count = 0;
public **synchronized** void add(int value){
this.count += value;
}
public **synchronized** void subtract(int value){
this.count -= value;
}
}
```
## Synchronized Static Methods
Synchronized static methods are synchronized on the class object of the class the synchronized static method belongs to. Since only one class object exists in the Java VM per class, only one thread can execute inside a static synchronized method in the same class.
In case a class contains more than one static synchronized method, only one thread can execute inside any of these methods at the same time.
```
public static MyStaticCounter{
private static int count = 0;
public **static synchronized** void add(int value){
count += value;
}
public **static synchronized** void subtract(int value){
count -= value;
}
}
```
## Synchronized Blocks in Instance Methods
```
public void add(int value){
synchronized(this){
this.count += value;
}
}
```
The object taken in the parentheses by the synchronized construct is called a monitor object. The code is said to be synchronized on the monitor object. Only one thread can execute inside a Java code block synchronized on the same monitor object.
## Synchronized Blocks in Static Methods
```
public class MyClass {
public static synchronized void log1(String msg1, String msg2){
log.writeln(msg1);
log.writeln(msg2);
}
public static void log2(String msg1, String msg2){
synchronized(MyClass.class){
log.writeln(msg1);
log.writeln(msg2);
}
}
}
```
Only one thread can execute inside any of these two methods at the same time because they are synchronized on the same object.
# What Objects to Synchronize On
It is possible to synchronize on any object. However, it is not recommended to synchronized on String object or any primitive type wrapper objects. This is because the compiler might optimize these types so that the same instance is used in different places in your code where you though you were using different instances.
For example, different strings with identical contents might point to the same object due to the string pool optimization. If you have more than one synchronized block that is synchronized on the literal String value "Hey", then the compiler might actually use the same String object behind the scenes. The result being, that both of these two synchronized blocks are then synchronized on the same object.
# Synchronized Block Limitations and Alternatives
Synchronized blocks in Java only allow a single thread to enter at a time. However, what if two threads just wanted to read a shared value, and not update it? That might be safe to allow. As alternative to a synchronized block you could guard the code with a `Read / Write Lock` which has more advanced locking semantics than a synchronized block.
There is no way to allow N number of threads to enter a specific synchronized block. The Java `semaphone` class can be used to achieve this.
Synchronized blocks do not guarantee in what order threads waiting to enter them are granted access. There is no fairness.
# Synchronized Block Performance Overhead
There is a small performance overhead associated with entering and exiting a synchronized block in Java. As Java has evolved, this performance overhead has gone down, but there is still a small price to pay.
The performance overhead of entering and exiting a synchronized block is mostly something to worry about if you enter and exit a synchronized block lots of times within a tight loop or so.
Also, try not to have larger synchronized blocks than necessary. In other words, only synchronize the operations that are really necessary to synchronize - to avoid blocking other threads from executing operations that do not have to be synchronized. Only the absolutely necessary instructions in synchronized blocks. That should increase parallelism of your code.
# Synchronized Block Reentrance
Once a thread has entered a synchronized block, the thread is said to "hold the lock" on the monitoring object the synchronized block is synchronized on. If the thread calls another method which calls back to the first method with the synchronized block inside, the thread holding the lock can reenter the synchronized block. It is not blocked just because a thread (itself) is holding the lock. Only if a different thread is holding the lock.
Keep in mind that designs where a thread enters into multiple synchronized blocks may lead to `nested monitor lockout` if the code is not designed carefully.