Differencebetween a Synchronized Method and Synchronized Block in Java

Why is synchronized block better than synchronized method?

It's not a matter of better, just different.

When you synchronize a method, you are effectively synchronizing to the object itself. In the case of a static method, you're synchronizing to the class of the object. So the following two pieces of code execute the same way:

public synchronized int getCount() {
// ...
}

This is just like you wrote this.

public int getCount() {
synchronized (this) {
// ...
}
}

If you want to control synchronization to a specific object, or you only want part of a method to be synchronized to the object, then specify a synchronized block. If you use the synchronized keyword on the method declaration, it will synchronize the whole method to the object or class.

Difference between synchronized(this) and few synchronized methods of class

No, they are the same.

private synchronized void foo() {}

private void foo2() {
synchronized(this){
}
}

They will do the exact same as both monitor the instance which they are called from.

A good tutorial can be found in the blog of Jakob Jenkov
http://tutorials.jenkov.com/java-concurrency/synchronized.html#java-synchronized-example

Happy coding!

Difference between synchronized method and synchronized block

A quick test using the Java code posted at the bottom of this answer resulted in the synchronized method being faster. Running the code on a Windows JVM on an i7 resulted in the following averages

synchronized block: 0.004254 s

synchronized method: 0.001056 s

This would imply that the synchronized method is actually faster as per your byte-code assessment.

What confused me, however, was the stark difference in the 2 times. I would have presumed that the JVM would still have a lock on the underlying synchronized method and the difference in times would be negligible, this was not the end result however. Since the Oracle JVM is closed, I took a look at the OpenJDK hotspot JVM source and dug into the byte code interpreter that handles the synchronization methods/blocks. To reiterate, the following JVM code is for the OpenJDK, but I would presume the official JVM has something similar in nature to how it handles the situation.

When a .class file is built, if a method is synchronized, byte code is put in that alerts the JVM that the method is synchronized (similar to byte code being added if the method is static/public/final/varargs, etc.), and the underlying JVM code sets a flag on the method structure to this effect.

When the byte-code interpreter hits byte-code for method invocation, the following code is called before the method is invoked that checks if it needs to be locked:

case method_entry: {
/* CODE_EDIT: irrelevant code removed for brevities sake */

// lock method if synchronized
if (METHOD->is_synchronized()) {
// oop rcvr = locals[0].j.r;
oop rcvr;
if (METHOD->is_static()) {
rcvr = METHOD->constants()->pool_holder()->java_mirror();
} else {
rcvr = LOCALS_OBJECT(0);
VERIFY_OOP(rcvr);
}
// The initial monitor is ours for the taking
BasicObjectLock* mon = &istate->monitor_base()[-1];
oop monobj = mon->obj();
assert(mon->obj() == rcvr, "method monitor mis-initialized");

bool success = UseBiasedLocking;
if (UseBiasedLocking) {
/* CODE_EDIT: this code is only run if you have biased locking enabled as a JVM option */
}
if (!success) {
markOop displaced = rcvr->mark()->set_unlocked();
mon->lock()->set_displaced_header(displaced);
if (Atomic::cmpxchg_ptr(mon, rcvr->mark_addr(), displaced) != displaced) {
// Is it simple recursive case?
if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
mon->lock()->set_displaced_header(NULL);
} else {
CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);
}
}
}
}

/* CODE_EDIT: irrelevant code removed for brevities sake */

goto run;
}

Then, when the method completes and returns to the JVM function handler, the following code is called to unlock the method (note that the boolean method_unlock_needed is set before the the method is invoked to bool method_unlock_needed = METHOD->is_synchronized()):

if (method_unlock_needed) {
if (base->obj() == NULL) {
/* CODE_EDIT: irrelevant code removed for brevities sake */
} else {
oop rcvr = base->obj();
if (rcvr == NULL) {
if (!suppress_error) {
VM_JAVA_ERROR_NO_JUMP(vmSymbols::java_lang_NullPointerException(), "");
illegal_state_oop = THREAD->pending_exception();
THREAD->clear_pending_exception();
}
} else {
BasicLock* lock = base->lock();
markOop header = lock->displaced_header();
base->set_obj(NULL);
// If it isn't recursive we either must swap old header or call the runtime
if (header != NULL) {
if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) {
// restore object for the slow case
base->set_obj(rcvr);
{
// Prevent any HandleMarkCleaner from freeing our live handles
HandleMark __hm(THREAD);
CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base));
}
if (THREAD->has_pending_exception()) {
if (!suppress_error) illegal_state_oop = THREAD->pending_exception();
THREAD->clear_pending_exception();
}
}
}
}
}
}

The statements CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception); and CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base));, and more specifically the functions InterpreterRuntime::monitorenter and InterpreterRuntime::monitorexit are the code that is called in the JVM for both synchronized methods and blocks to lock/unlock the underlying objects. The run label in the code is the massive byte-code interpreter switch statement that handles the different byte codes being parsed.

From here, if a synchronized block opcode (the monitorenter and monitorexit byte-codes) is encountered, the following case statements are run (for monitorenter and monitorexit respectively):

CASE(_monitorenter): {
oop lockee = STACK_OBJECT(-1);
// derefing's lockee ought to provoke implicit null check
CHECK_NULL(lockee);
// find a free monitor or one already allocated for this object
// if we find a matching object then we need a new monitor
// since this is recursive enter
BasicObjectLock* limit = istate->monitor_base();
BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base();
BasicObjectLock* entry = NULL;
while (most_recent != limit ) {
if (most_recent->obj() == NULL) entry = most_recent;
else if (most_recent->obj() == lockee) break;
most_recent++;
}
if (entry != NULL) {
entry->set_obj(lockee);
markOop displaced = lockee->mark()->set_unlocked();
entry->lock()->set_displaced_header(displaced);
if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) {
// Is it simple recursive case?
if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
entry->lock()->set_displaced_header(NULL);
} else {
CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
}
}
UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
} else {
istate->set_msg(more_monitors);
UPDATE_PC_AND_RETURN(0); // Re-execute
}
}

CASE(_monitorexit): {
oop lockee = STACK_OBJECT(-1);
CHECK_NULL(lockee);
// derefing's lockee ought to provoke implicit null check
// find our monitor slot
BasicObjectLock* limit = istate->monitor_base();
BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base();
while (most_recent != limit ) {
if ((most_recent)->obj() == lockee) {
BasicLock* lock = most_recent->lock();
markOop header = lock->displaced_header();
most_recent->set_obj(NULL);
// If it isn't recursive we either must swap old header or call the runtime
if (header != NULL) {
if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) {
// restore object for the slow case
most_recent->set_obj(lockee);
CALL_VM(InterpreterRuntime::monitorexit(THREAD, most_recent), handle_exception);
}
}
UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
}
most_recent++;
}
// Need to throw illegal monitor state exception
CALL_VM(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD), handle_exception);
ShouldNotReachHere();
}

Again, the same InterpreterRuntime::monitorenter and InterpreterRuntime::monitorexit functions are called to lock the underlying objects, but with much more overhead in the process, which explains why there is the difference in times from a synchronized method and synchronized block.

Obviously both the synchronized method and synchronized block have their pros/cons to consider when using, but the question was asking about which is faster, and based on the preliminary test and the source from the OpenJDK, it would appear as though the synchronized method (alone) is indeed faster than a synchronized block (alone). Your results may vary though (especially the more complex the code is), so if performance is an issue it's best to do your own tests and gauge from there what might make sense for your case.

And here's the relevant Java test code:

Java Test Code

public class Main
{
public static final Object lock = new Object();
private static long l = 0;

public static void SyncLock()
{
synchronized (lock) {
++l;
}
}

public static synchronized void SyncFunction()
{
++l;
}

public static class ThreadSyncLock implements Runnable
{
@Override
public void run()
{
for (int i = 0; i < 10000; ++i) {
SyncLock();
}
}
}

public static class ThreadSyncFn implements Runnable
{
@Override
public void run()
{
for (int i = 0; i < 10000; ++i) {
SyncFunction();
}
}
}

public static void main(String[] args)
{
l = 0;
try {
java.util.ArrayList<Thread> threads = new java.util.ArrayList<Thread>();
long start, end;
double avg1 = 0, avg2 = 0;
for (int x = 0; x < 1000; ++x) {
threads.clear();
for (int i = 0; i < 8; ++i) { threads.add(new Thread(new ThreadSyncLock())); }
start = System.currentTimeMillis();
for (int i = 0; i < 8; ++i) { threads.get(i).start(); }
for (int i = 0; i < 8; ++i) { threads.get(i).join(); }
end = System.currentTimeMillis();
avg1 += ((end - start) / 1000f);
l = 0;
threads.clear();
for (int i = 0; i < 8; ++i) { threads.add(new Thread(new ThreadSyncFn())); }
start = System.currentTimeMillis();
for (int i = 0; i < 8; ++i) { threads.get(i).start(); }
for (int i = 0; i < 8; ++i) { threads.get(i).join(); }
end = System.currentTimeMillis();
avg2 += ((end - start) / 1000f);
l = 0;
}
System.out.format("avg1: %f s\navg2: %f s\n", (avg1/1000), (avg2/1000));
l = 0;
} catch (Throwable t) {
System.out.println(t.toString());
}
}
}

Hope that can help add some clarity.

What is the difference between a synchronized method and synchronized block in Java?

A synchronized method uses the method receiver as a lock (i.e. this for non static methods, and the enclosing class for static methods). Synchronized blocks uses the expression as a lock.

So the following two methods are equivalent from locking prospective:

synchronized void mymethod() { ... }

void mymethod() {
synchronized (this) { ... }
}

For static methods, the class will be locked:

class MyClass {
synchronized static mystatic() { ... }

static mystaticeq() {
syncrhonized (MyClass.class) { ... }
}
}

For synchronized blocks, you can use any non-null object as a lock:

synchronized (mymap) {
mymap.put(..., ...);
}

Lock scope

For synchronized methods, the lock will be held throughout the method scope, while in the synchronized block, the lock is held only during that block scope (otherwise known as critical section). In practice, the JVM is permitted to optimize by removing some operations out of the synchronized block execution if it can prove that it can be done safely.

What is the difference between synchronized methods and blocks?

A synchronized method locks the monitor associated with the instance of the class (ie 'this') or the class (if a static method) and prevents others from doing so until the return from the method. A synchronized block can lock any monitor (you tell it which) and can have a scope smaller than that of the encolsing method.

Synchronized blocks are prefered if they don't end up equivalent to the entire scope of the method and/or if they lock something less draconian than the instance (or class if static).

What is the difference between synchronized(this) and synchronized method

The two different methods are functionally equivalent. There may be a very small performance difference:

At the bytecode level, the synchronized method advertises its need for synchronization as a bit set in the method's access flag. The JVM looks for this bit flag and synchronizes appropriately.

The synchronized block implements its synchronization through a sequence of bytecode operations stored in the class file's definition of the method.

So the synchronized method might potentially execute slightly faster and take up less space in terms of bytecode.

Again, the two are, by specification, functionally identical.

I'm guessing that the performance difference is negligible and code style guidelines should win out. Some compilers might even optimize away the block into an access flag. And JIT may take the performance difference away.

What is the difference between a synchronized function and synchronized block?

it the first one only one thread can execute whole method at a time whereas in second one only one thread can execute that synchronized block if not used this as parameter.

here is a duplicate of it Is there an advantage to use a Synchronized Method instead of a Synchronized Block?

What is different between method synchronized vs object synchronized ?

tl;dr - external synchronization opens you up to attack (intentional or otherwise), and also forces you to lock checking that might not be necessary. Also there's nerdy-good information in at the very bottom of this answer.

A synchronized method is almost identical (see bottom) to synchronizing on this:

synchroinzed void foo() {

}

void foo() {
synchronized(this) {

}
}

By making the method itself not synchronized, you allow yourself to lock on any Object, not just this. I personally would recommend synchronizing on an internal Object, like so

private final Object foolock = new Object();

void foo() {
synchronzied(foolock) {

}
}

The reason is, if you do a synchronized method, which effectively locks this someone else could synchronize on you and lock you out of your Object! Imagine the following:

class FooDoer {
// removed! using synchronized methods instead
//final Object foolock = new Object();

synchronized void foo() {

}
}

// thread 1 - attacker
FooDoer f = new FooDoer();
globalMap.put("TheFoo",f);
synchronized(f) {
while(true); // haha!
}

// thread 2 - victim
FooDoer f = globalMap.get("TheFoo");
f.foo(); // locked, because Thread 1 has locked us out!

It opens yourself up to a denial of service attack. That's not good! By making the lock internal, you as the author of class get to control exactly who can lock what areas of your object and under what terms.

The other issue is that you might not have protected data for checking. For example:

synchronized void foo() {
if(expensiveAccessCheck()) {
update();
}
}

void foo() {
if(expensiveAccessCheck()) {
synchronized(foolock) {
update();
}
}
}

In this scenario, you don't have to make everyone else wait while you sit there spinning your wheels. Perhaps you're scraping data off a URL and then updating. Why make everyone else stay locked out of the data? The lower granularity is better in this case.

Now you may recall I said almost identical earlier. There is a tiny, tiny, tiny difference between the two. A synchronized method will bake the instruction to synchronize right into the method signature in the bytecode. This will make the bytecode 1 byte shorter, because it doesn't need to make the extra call. This might have a small impact because the number of bytes in the method's bytecode is one of the factors in determining whether or not to inline. In spite of this minutia, I highly recommend treating them as the same because this is a micro-optimization that will hardly ever play out as significant in a production setting. It just wouldn't be complete to call it identical when they aren't.

What is more efficient - synchronization on a method or a block

If you synchronize the method, then the whole method is synchronized so only one thread can execute that method at a time. If you synchronize a code block within that method then more than one thread can execute the method simultaneously, but only one thread can enter the synchronized block at a time.

From this we can conclude that synchronizing on the smallest possible code block required is the most efficient way to do it. However the practical difference between synchronizing a method vs. a code block really depends on the method and what code is being left out of the synchronized block.

What does A synchronized block in Java is synchronized on some object mean..?

The effect of synchronized is that only one thread at a time can execute the synchronized code. But if we look at the details, that's not the whole truth.

Suppose we have two Vectors A and B and want to call various methods from different threads. The Vector class is thread-safe by synchronizing all important methods. When thread T1 executes A.add(5,"abc"), why should that block a different thread from executing B.get(5)? They have no data elements in common, so executing both calls in parallel won't hurt.

And here comes the notion of "synchronized on A": The Vector methods synchronize on the Vector instance, so at most one thread can execute synchronized code for any given Vector.

So Vector A synchronizes on A, and Vector B on B. So, no two threads can manipulate the Vector A in parallel, but one thread can work on A, and another one independently on B.

  • With the synchronized(object) { ... } construct, you decide on the object you want to synchronize on.
  • Using the synchronized keyword on an instance method, you get synchronization on the current (this) object, so every instance gets its own synchronization.
  • Using the synchronized keyword on a static method, you get synchronization on the class, so you get protection against all other static synchronized methods of this class, independent of any instance.


Related Topics



Leave a reply



Submit