1

What is the difference between this two?

public void someMethod(){

     synchronized(this){
      //some code

      }
}

and

public void someMethod(){

   Object lock = new Object();
   synchronized(lock){
   //some code

    }

}

Also please make me clear, If I mention an object inside the Synchronize parenthesis, is that mean, I will be able to use thread safe for that particular object?

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
Amartya
  • 29
  • 3
  • 2
    The second is pointless. You synchronize code to control repeated invoking by different threads. Creating a new lock to sync on each time is like *not synchronizing* at all. – GhostCat Aug 19 '18 at 06:17
  • synchronization deals with Sharing of a critical section (statements) of code within multiple Threads such that one thread executes it at a time. Local variable `lock` gets initialized each time the method is being invoked. Now each thread will create a different object and hence it will **not be shared**. Now whatever critical statements you have within synchronized block will be guarded by different lock objects. You have multiple threads working on same *critical section* at same time and synchronization although applied is not effective at all. – nits.kk Aug 19 '18 at 07:18
  • `this` is shared by all the instance methods. It is not something which is local to a method. Hence synchronization works. Multiple threads will access critical section of code guarded by synchronized block on `this` will enter critical section at a time as `this` is shared by all the threads entering an instance method – nits.kk Aug 19 '18 at 07:21
  • The answers on the "duplicate" don't answer this question. The other question was answered by explaining what `this` means. But, what we have here is a question about what `synchronized` means. – Solomon Slow Aug 19 '18 at 15:43
  • No, `synchronized(obj)` does _not_ protect `obj` from access by other threads. The main thing it does is, it stops other threads from entering any block of code that is synchronized on the same object. You can use that feature to protect `obj` or, you can use it to protect any _other_ variables. But, it's up to you to ensure that the variable (or variables) that you want to protect are only ever accessed from inside `synchronized` blocks that all synchronize on the same object. – Solomon Slow Aug 19 '18 at 15:53

2 Answers2

3

When using synchronized keyword, you need an object as monitor lock. Only threads using the same monitor lock will be synchronized.

  • synchronized(this) synchronized on current instance. Check this keyword in Java.

    • When calling someMethod on the same instance from different threads, these threads will be synchronized.
    • When calling someMethod on the different instances from different threads, these threads will not be synchronized.
  • The second version does not have any synchronization function, since every thread has their own method stack, and they will create their own Object lock on their method stack.

xingbin
  • 27,410
  • 9
  • 53
  • 103
  • But I am getting some different result. – Amartya Aug 19 '18 at 06:45
  • @AmartyaKaran, Synchronization-related bugs are notoriously difficult to find and reproduce. I have analyzed crash dumps from customer sites, and found bugs in a large, multi-threaded software system that passed all of its tests and ran for the equivalent of several years in the field before the bug revealed itself. – Solomon Slow Aug 19 '18 at 15:28
1

Before we get into the differences, let's first try and understand what is this keyword in JAVA. An instance of a class can refer to itself using this. One can use this keyword to access class members as well (only non-static ones).

Now synchronization in JAVA is based on Objects, where each Object maintains a monitor which allows only one thread to access synchronized code block (or synchronized method). Therefore, it is important that same object is shared across different threads in order for them to synchronize correctly.

First version above ensures correct synchronization when same instance of that class is shared across multiple threads.

The second version is basically creating a new Object every time someMethod is called, which means even if the same instance of that class was shared across multiple threads, each of those threads would synchronize on different copy of lock object, thus effectively leading to no synchronization.

To make things a little more clear, here are some other variants of first version.

public void someMethod() {
 // Note that assignment below is redundant and is shown for example purposes.
 Object lock = this;
 synchronized(lock){
    //some code
  }
}

public synchronized void someMethod() {
 //some code
}

As for which version should one select. This totally depends on what method does.

If all operations performed by method requires synchronization, then I prefer to use synchronized method (last option). This prevents an extra indentation and is slightly more readable. Otherwise, first variant makes sense where you can perform operations that do not require synchronization outside synchronized block.

AllThatICode
  • 1,250
  • 13
  • 19
  • But I am getting some different result. I have a Demothread class public class Demothread { void display(){ for(int j=0;j<200;j++){System.out.println(j);} } } I have created two Thread. Made an object reference of Demothread class. Now I am calling # Thread 1 # calling display() within a synchronized block of demoted object # Thread 2 # calling display() without synchronized block . What will be result? – Amartya Aug 19 '18 at 07:01
  • Without looking at your code, it is unclear what you are trying to do. – AllThatICode Aug 19 '18 at 07:10
  • Re, "...effectively leading to incorrect synchronizaion." I would have said, "effectively _no_ synchronization." – Solomon Slow Aug 19 '18 at 15:21
  • SGTM. Thanks for the suggestion. – AllThatICode Aug 20 '18 at 05:29