Asked  7 Months ago    Answers:  5   Viewed   40 times

Can any one tell me the advantage of synchronized method over synchronized block with an example?

 Answers

78

Can anyone tell me the advantage of the synchronized method over the synchronized block with an example? Thanks.

There is not a clear advantage of using synchronized method over the block.

Perhaps the only one ( but I wouldn't call it an advantage ) is you don't need to include the object reference this.

Method:

public synchronized void method() { // blocks "this" from here.... 
    ...
    ...
    ...
} // to here

Block:

public void method() { 
    synchronized( this ) { // blocks "this" from here .... 
        ....
        ....
        ....
    }  // to here...
}

See? No advantage at all.

Blocks do have advantages over methods though, mostly in flexibility because you can use another object as lock whereas syncing the method would lock the entire object.

Compare:

// locks the whole object
... 
private synchronized void someInputRelatedWork() {
    ... 
}
private synchronized void someOutputRelatedWork() {
    ... 
}

vs.

// Using specific locks
Object inputLock = new Object();
Object outputLock = new Object();

private void someInputRelatedWork() {
    synchronized(inputLock) { 
        ... 
    } 
}
private void someOutputRelatedWork() {
    synchronized(outputLock) { 
        ... 
    }
}

Also if the method grows you can still keep the synchronized section separated:

 private void method() {
     ... code here
     ... code here
     ... code here
    synchronized( lock ) { 
        ... very few lines of code here
    }
     ... code here
     ... code here
     ... code here
     ... code here
}
Tuesday, June 1, 2021
 
Akdeniz
answered 7 Months ago
96

The snippet synchronized(X.class) uses the class instance as a monitor. As there is only one class instance (the object representing the class metadata at runtime) one thread can be in this block.

With synchronized(this) the block is guarded by the instance. For every instance only one thread may enter the block.

synchronized(X.class) is used to make sure that there is exactly one Thread in the block. synchronized(this) ensures that there is exactly one thread per instance. If this makes the actual code in the block thread-safe depends on the implementation. If mutate only state of the instance synchronized(this) is enough.

Wednesday, June 2, 2021
 
Yarin
answered 7 Months ago
41

When you state that a method throws an exception you are saying to the caller:

You have two choices:

  1. Redeclare yourself as throwing the same exception.
  2. Catch the exception and deal with it.

In case 1 it may remind user to implement a finally - which could be a bonus.

In case 2 it focuses the mind on the exception which could also be a bonus.

If you hide that possibility then neither of the above reminders occur to the user.

To me one may unnecessarily clutter up their code while the other keeps it sweet and simple. However, one encourages focus on potential issues while the other may leave you in blissful ignorance.

Bottom line - Ask yourself how irritating it will be to declare the exception as thrown (e.g. should you declare throws NullPointerException? - NO!) and is this irritation balanced by the upside of focusing the users mind on catch, finally and throws.

Thursday, August 5, 2021
 
ProfK
answered 4 Months ago
22

It depends on what you're trying to accomplish. One of the cool things about blocks is that they capture local scope. You can achieve the same end result with a function, but you end up having to do something like pass around a context object full of relevant values. With a block, you can do this:

int num1 = 42;
void (^myBlock)(void) = ^{
    NSLog(@"num1 is %d", num1);
};

num1 = 0; // Changed after block is created

// Sometime later, in a different scope

myBlock();              // num1 is 42

So simply by using the variable num1, its value at the time myBlock was defined is captured.

From Apple's documentation:

Blocks are a useful alternative to traditional callback functions for two main reasons:

  1. They allow you to write code at the point of invocation that is executed later in the context of the method implementation. Blocks are thus often parameters of framework methods.

  2. They allow access to local variables. Rather than using callbacks requiring a data structure that embodies all the contextual information you need to perform an operation, you simply access local variables directly.

Tuesday, August 17, 2021
 
xenon
answered 4 Months ago
91

Ok let's have a look at the different possibilities you mention:

1.

for (int ii=0; ii<NUM_EVENTS; ++ii) {
  synchronized( monitor) {
    synchronized(cnt) {        // <-- is this synchronized necessary?
      monitor.add(cnt);
    }
    synchronized(cnt) {
      cnt++;        // <-- why does moving the synchronized block to here result in the correct value for cnt?
    }
}

First the monitor object is shared between the threads, therefore getting a lock on it (that is what synchronized does) will make sure that the code inside of the block will only be executed by one thread at a time. So the 2 synchronized inside of the outer one are not necessary, the code is protected anyway.

2.

for (int ii=0; ii<NUM_EVENTS; ++ii) {
  synchronized( monitor) {
    monitor.add(cnt);
  }
  synchronized(cnt) {
    cnt++;              // <-- why does moving the synchronized block here result in cnt being wrong?
  }
}

Ok this one is a little bit tricky. cnt is an Integer object and Java does not allow modifying an Integer object (Integers are immutable) even though the code suggests that this is what is happening here. But what acutally will happen is that cnt++ will create a new Integer with the value cnt + 1 and override cnt. This is what the code actually does:

synchronized(cnt) {
  Integer tmp = new Integer(cnt + 1);
  cnt = tmp;
}

The problem is that while one thread will create a new cnt object while all other threads are waiting to get a lock on the old one. The thread now releases the old cnt and will then try to get a lock on the new cnt object and get it while another thread gets a lock on the old cnt object. Suddenly 2 threads are in the critical section, executing the same code and causing a race condition. This is where the wrong results come from.

If you remove the first synchronized block (the one with monitor), then your result gets even more wrong because the chances of a race increase.

In general you should try to use synchronized only on final variables to prevent this from happening.

Monday, August 23, 2021
 
Jesse
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share