I was thinking to improve my threading fundamentals, so I
planned to make few notes for myself that will assist me in future (Obviously
at the time of Interviews). Following questions and answers have been taken
from stackoverflow.com. This post is a sticky notes post for me.
Let’s look at some code to know Synchronized method and
Synchronized block.
Synchronized method
public synchronized void synchronizedMethod(){ //Do something in this method }
Synchronized block
public void
synchronizedBlock(){
//Do Something
before Synchronization
synchronized(this){
//Do
Something here in synchronized block.
}
//Do Something
after Synchronization
}
When static method is synchronized, then class’s object (created
by Class.forName()) is locked whereas in
case of instance method, class’s instance (this) is locked.
When a block is synchronized, then developer has to choose
the object to lock. JVM implicitly do not lock anything here.
Something that JSR
says
A synchronized statement acquires a mutual-exclusion lock
on behalf of the executing thread, executes a block, and then releases the
lock. While the executing thread owns the lock, no other thread may acquire the
lock.
A synchronized method acquires a
monitor before it executes. For a class (static) method, the monitor associated
with the Class object for the method's class is used. For an instance
method, the monitor associated with this (the object for which the
method was invoked) is used.
These are the same locks that can be used by
the synchronized statement; thus, the code:
class Test {
int count;
synchronized void bump() { count++; }
static int classCount;
static synchronized void classBump() {
classCount++;
}
}
Has exactly the same effect as:
class BumpTest {
int count;
void bump() {
synchronized (this) {
count++;
}
}
static int classCount;
static void classBump() {
try {
synchronized (Class.forName("BumpTest")) {
classCount++;
}
} catch (ClassNotFoundException e) {
...
}
}
}
Difference between
block and method
Lock scope
For synchronized methods, the lock will be held throughout
the method scope, whereas in the synchronized blocks, the lock is held
only during the synchronized block (otherwise known as critical
section).
Objects
In synchronized method, implicit monitor (this) is obtained,
whereas in case of blocks developer has to decide the object to lock.
When the JVM executes a synchronized method, the executing
thread identifies that the method's method_info structure has the ACC_SYNCHRONIZED flag
set, then it automatically acquires the object's lock, calls the method, and
releases the lock. If an exception occurs, the thread automatically releases
the lock.
Synchronizing a method block, on the other hand, bypasses
the JVM's built-in support for acquiring an object's lock and exception
handling and requires that the functionality be explicitly written in byte
code. If you read the byte code for a method with a synchronized block, you
will see more than a dozen additional operations to manage this functionality.
Listing 1 shows calls to generate both a synchronized method and a synchronized
block.
package com.geekcap;
public class SynchronizationExample {
private int i;
public
synchronized int synchronizedMethodGet() {
return i;
}
public int
synchronizedBlockGet() {
synchronized( this ) {
return
i;
}
}
}
|
The synchronizedMethodGet() method generates the
following byte code:
0: aload_0
1: getfield
2: nop
3: iconst_m1
4: ireturn
|
And here's the byte code from the synchronizedBlockGet() method:
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: aload_0
5: getfield
6: nop
7: iconst_m1
8: aload_1
9: monitorexit
10: ireturn
11: astore_2
12: aload_1
13: monitorexit
14: aload_2
15: athrow
|
Creating the synchronized block yielded 16 lines of bytecode, whereas synchronizing the method returned just 5.
So here is piece
of advice whenever you think of using synchronized block, think of
minimizing the synchronized code, if you want to synchronize the complete code
within the method, then do not push your mind hard and let JVM optimize the
code for you.
A quote from Effective Java 2nd Edition,
Item 67: Avoid excessive synchronization:
As a rule, you should do as little work as possible inside
synchronized
regions.
No comments:
Post a Comment