0

I have simple question but has problem to find answer on it.

Question is if synchronized method is equal to synchronized(this) - mean do same locking.

I want to write thread safe code with reduced thread locking (not want use always synchronized methods but sometime partial synchronization critical sections only).

Could you explain me if this code is equal or not and why in short words (examples is simplified to show atomic problem)?

Examples

Is this mixed locking code is equal to brute force code bellow:

public class SynchroMixed {
    int counter = 0;

    synchronized void writer() {
        // some not locked code
        int newCounter = counter + 1;

        // critical section
        synchronized(this) {
            counter = newCounter;
        }
    }

    synchronized int reader() {
        return counter;
    }
}

Brute force code (each method is locked including not critical section:

public class SynchroSame {
    int counter = 0;

    synchronized void writer() {
        int newCounter = counter + 1;

        counter = newCounter;
    }

    synchronized int reader() {
        return counter;
    }
}

Or I should write this code (this is for sure valid but more micro coding and unclear).

public class SynchroMicro {
    int counter = 0;

    void writer() {
        // some not locked code
        int newCounter = counter + 1;

        // critical section
        synchronized(this) {
            counter = newCounter;
        }
    }

    int reader() {
        synchronized (this) {
            return counter;
        }
    }
}
Chameleon
  • 9,722
  • 16
  • 65
  • 127
  • In your first example, the "*some not locked code*" statement is still within a `synchronized` method. Is this what you intended or a typo? – Bruno Mar 13 '13 at 11:18
  • 1
    Exactly the same, have a look at this [link][1] [1]: http://stackoverflow.com/questions/574240/synchronized-block-vs-synchronized-method – javadev Mar 13 '13 at 11:20

4 Answers4

3

synchronized method and synchronized(this) means absolutely the same thing, and uses the same mutex behind. It's more question of taste what notation to prefer.

Personally I prefer synchronized(this), because it explicitly specifies the scope of the mutex lock which could be smaller than the whole method

nogard
  • 9,432
  • 6
  • 33
  • 53
  • 1
    Also: `synchronized(this)` inside a `synchronized` method will have absolutely no effect. – Joachim Sauer Mar 13 '13 at 11:19
  • @JoachimSauer: Yes, since Java mutexes are reentrant there is no effect – nogard Mar 13 '13 at 11:21
  • @JoachimSauer I make mistake in code method is not synchronized - removed it now from code - there is not sense double synchronized since first cover second as you said. – Chameleon Mar 13 '13 at 11:30
  • I prefer short notation `synchronized' and `synchronized(this)` if it equal and more Python than Java since more flexible - you could write type checking code but you could avoid it and strip 50% of decorations and could use multiple inheritance - you could make class from many classes (Java force code cloning not reduction). – Chameleon Mar 13 '13 at 11:34
2

There is definitely no point in synchronized(this) within a synchronized method since entering the method is already implicitly synchronized(this).

That was just a syntax mistake on your part since you clearly intend to reduce the scope of the critical section, but the reduced scope introduces a data race into your code: you must both read and write the shared variable within the same synchronized block.

In addition, even if a method only reads the shared variable, it still must do that in a synchronized block; otherwise it may never observe any writes by other threads. This is the basic semantics of Java's Memory Model.

Now, if what you are showing is really representative of your full problem, then you shouldn't even be using synchronized, but a simple AtomicInteger, which will have the best concurrent performance.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • I just use int and example - good answer! As you found there is mistake since 'synchronize' over 'synchronized(this)' has no sense - I forget delete modifier from method. – Chameleon Mar 13 '13 at 11:38
2

All three examples are equivalent. Using synchronized on a method is the same as wrapping the entire body within synchronized(this) {}.

Then, by using synchronized(this) {} for some statements, the thread is only re-acquiring a lock it already owns: it's pointless here.

Bruno
  • 119,590
  • 31
  • 270
  • 376
2

Synchronized method and block are absolutely similar from functional point of view. They both do the same task i.e. to avoid concurrent access to particular method or block of code within a method.

synchronized() block is more flexible and handy when you have a long method and just need a part of it to be synchronized. You need not lock access to the entire method, as we know synchronization has some performance issues associated with it. Hence it is always recommended to synchronize only need part of the code and not the entire method (if not required).

Ankur Shanbhag
  • 7,746
  • 2
  • 28
  • 38