2

I found 2 ways for synchronize method:

First:

public static Integer number = 0;

 public synchronized static void myMethod(){
        number++;
        number--;
    }

Second:

    public static Integer number = 0;
    private static final Object mySemaphoreLock = new Object();

public static void myMethod(){
        synchronized (mySemaphoreLock){
            number++;
            number--;
        }
    }

Are these two methods the same? What is the difference between them?

Radiodef
  • 37,180
  • 14
  • 90
  • 125
discCard
  • 421
  • 1
  • 5
  • 16
  • 1
    There are far more ways than two. The main difference here is that the first method the lock is visible to the caller (and everyone else) and anyone can take and hold that lock if they have access to the object's reference. – markspace Sep 23 '18 at 19:38

2 Answers2

3

In the second case lock object s available only for your class. In the first method some other code can acquire lock accidentally or on purpose and make your code not working as expected.

For example if first case it is possible to do the following

public class MyBadClass {

  public static void badStuff() {  //Acquire lock on class object and do forever loop. Because of that you will not be able to call YourClass.myMethod() in your first option
    synchronized (YourClass.class) {
      while(true);
    }
 }
}
Ivan
  • 8,508
  • 2
  • 19
  • 30
1

These two methods are using different objects to synchronize on (class instance vs class field).


Your first method:

public synchronized static void myMethod(){
    number++;
    number--;
}

can be expressed as

public static void myMethod(){
    synchronized (YourClass.class) {
        number++;
        number--;
    }
}

so you are using a different object to synchronize on (YourClass's class object vs class's static field (mySemaphoreLock)) than

public static void myMethod() {
    synchronized (mySemaphoreLock) {
        number++;
        number--;
    }
}

In your example there's no difference, but you cannot rule out someone else (think 3rd-party code) that would also want to synchronize on your class's object (for reasons unknown) - that would impact the behaviour of your code. In general it would be some other code doing something like:

class SomeOtherClass {

public void someOtherMethod() {
    // for some reason SomeOtherClass synchronizes on YourClass.class
    synchronized (YourClass.class) {
        /* long running operation */
    }
}

}

so even if you invoke YourClass.myMethod() in parallel, one would need for to wait for the other to finish.

If you choose the implemenation with mySemaphoreLock, that wouldn't happen - this piece of code would execute concurrently (as they use different objects to synchronize on) - so no competition.

Adam Kotwasinski
  • 4,377
  • 3
  • 17
  • 40