From http://tutorials.jenkov.com/java-concurrency/synchronized.html
by Jakob Jenkov
Table of Contents
- The Java synchronized Keyword
- Synchronized Instance Methods
- Synchronized Static Methods
- Synchronized Blocks in Instance Methods
- Synchronized Blocks in Static Methods
- Java Synchronized Example
- Java Concurrency Utilities
A Java synchronized block marks a method or a block of code as synchronized. Java synchronized blocks can is used to avoid race conditions.
The Java synchronized Keyword
Synchronized blocks in Java is marked with the synchronized
keyword. A synchronized block in Java was synchronized on some object. All synchronized blocks synchronized to the same object can only has one thread executing inside them at the same time . All and threads attempting to enter the synchronized block is blocked until the thread inside the synchronized block Exits the block.
The synchronized
keyword can used to mark four different types of blocks:
- Instance methods
- Static methods
- Code blocks Inside instance methods
- Code blocks inside static methods
These blocks is synchronized on different objects. Which type of synchronized block you need depends on the concrete situation.
Synchronized Instance Methods
Here is a synchronized instance method:
synchronized void Add (int value) { This.count + = value; }
Notice the use of the synchronized
keyword in the method declaration. This tells Java, the method is synchronized.
A synchronized instance method in Java was synchronized on the instance (object) owning the method. Thus, each instance have its synchronized methods synchronized on a different object:the owning instance. Only one thread 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 Instan Ce. One thread per instance.
Synchronized Static Methods
Static methods is marked as synchronized just like instance methods using the synchronized
keyword. Here is a Java synchronized static Method Example:
static synchronized void Add (int value) { count + = value; }
Also here the synchronized
keyword tells Java, the method is synchronized.
Synchronized static methods is 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 synchronize D method in the same class.
If the static synchronized methods is located in different classes and then one thread can execute inside the static sync Hronized methods of each class. One thread per class regardless of which static synchronized method it calls.
Synchronized Blocks in Instance Methods
You don't have the to synchronize a whole method. Sometimes it is preferable to synchronize only part of a method. Java synchronized blocks inside methods makes this possible.
Here are a synchronized block of Java code inside an unsynchronized Java method:
public void Add (int value) { synchronized (this) { this.count + = value; } }
This example uses the Java synchronized block construct to mark a block of code as synchronized. This code would now execute as if it is a synchronized method.
Notice how the Java synchronized block construct takes a object in parentheses. In the example ' this ' is used, which are the instance the Add method is called on. The object taken in the parentheses by the synchronized construct is called a monitor object. The code is said to being synchronized on the monitor object. A Synchronized instance method uses the object it belongs to as monitor object.
Only one thread can execute inside a Java code block synchronized on the same monitor object.
The following examples is both synchronized on the instance they is called on. They is therefore equivalent with respect to synchronization:
public class MyClass { synchronized void Log1 (String msg1, String msg2) { Log.writeln (MSG1); Log.writeln (MSG2); } public void log2 (string msg1, String msg2) { synchronized (this) { Log.writeln (MSG1); Log.writeln (MSG2); } } }
Thus only a single thread can execute inside either of the and synchronized blocks in this example.
Had the second synchronized block been synchronized on a different object than this
, then one thread at a time had be En able to execute inside each method.
Synchronized Blocks in Static Methods
Here is the same examples as static methods. These methods is synchronized on the class object of the "The Methods belong to:
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 and methods at the same time.
Had the second synchronized block been synchronized on a different object than MyClass.class
, then one thread could execute in Side each method at the same time.
Java Synchronized Example
Here is a example that starts 2 threads and has both of them call the Add method on the same instance of Counter. Only one thread at a time would be able the Add method on the same instance, because the method is synchronized On the instance it belongs to.
public class counter{ Long Count = 0; Public synchronized void Add (Long value) { This.count + = value; } }
public class Counterthread extends thread{ protected Counter Counter = null; Public Counterthread (Counter Counter) { this.counter = Counter; } public void Run () {for (int i=0; i<10; i++) { counter.add (i);}} }
public class Example {public static void Main (string[] args) { Counter Counter = new Counter (); Thread Threada = new Counterthread (counter); Thread threadb = new Counterthread (counter); Threada.start (); Threadb.start (); } }
The threads is created. The same Counter
instance is passed to both of them in their constructor. Counter.add()
the method is synchronized on the instance, because the Add method was an instance method, and marked as synch Ronized. Therefore only one of the threads can, the Add () method at a time. The other thread would wait until the first thread leaves the Add () method, before it can execute the method itself.
If the threads had referenced Counter
and separate instances, there would have been no problems calling the Add () met Hods simultaneously. The calls would has been to different objects, so the methods called would also is synchronized on different objects (The object owning the method). Therefore the calls would not block. Here's how this could look:
public class Example {public static void Main (string[] args) { Counter Countera = new Counter (); Counter Counterb = new Counter (); Thread Threada = new Counterthread (Countera); Thread threadb = new Counterthread (counterb); Threada.start (); Threadb.start (); } }
Notice how the threads, Threada and threadb, no longer reference the same counter instance. The method of and is add
counterA
synchronized on their, counterB
owning instances. Calling on would add()
counterA
thus not block a call to add()
on counterB
.
Java Concurrency Utilities
The synchronized
mechanism was Java's first mechanism for synchronizing access to objects gkfx by multiple threads. The synchronized
mechanism isn ' t very advanced though. That's why Java 5 got a whole set of concurrency utility classes to help developers implement more fine grained concur Rency control than what do get with synchronized
.
Java Synchronized Blocks