Jamie
Jamie

Reputation: 3051

Synchronization on class object

I was reading a tutorial on concurreny when i read the following example:

Here are the same two examples as static methods. These methods are synchronized on the class object of the class the methods belong to:

    public class MyClass {

    public static synchronized void log1(String msg1, String msg2){
       log.writeln(msg1);
       log.writeln(msg2);
    }


    public static void log2(String msg1, String msg2){
       synchronized(MyClass.class){
          log.writeln(msg1);
          log.writeln(msg2);  
       }
    }
  }

Only one thread can execute inside any of these two methods at the same time.

Had the second synchronized block been synchronized on a different object than MyClass.class, then one thread could execute inside each method at the same time.

I just want to make sure that I get this right.

So you can't call in a single thread the methods log1 and log2 at the same time? But if the synchronized wasn't on the class object you could?

It's more the translation that is bothering me I guess.

An example with comments is appreciated.

Upvotes: 0

Views: 160

Answers (3)

ka4eli
ka4eli

Reputation: 5424

So you can't call in a single thread the methods log1 and log2 at the same time?

You can't call any 2 methods at the same time from single thread. You can call the same method from one thread and another thread at the same time.

When this situation occurs (if method is synchronized) first thread who acquire the lock (in your case it is MyClass.class) will execute synchronized block and then release the lock. Only after it another thread can try to acquire the lock and continue execution.

You have 2 methods both synchronized on MyClass.class. It means that if the first thread acquire MyClass.class lock (it can dot it by calling log1 or log2) then the second thread, if he wants to execute anything locked by MyClass.class (in your case any of the methods log1 or log2), must wait until first thread releases this lock to execute.

But if the synchronized wasn't on the class object you could?

This means that one of the methods is synchronized on MyClass.class and another is synchronized on something else (for non-static default is this). They have different locks so they can be executed simultaneously from different threads.

Upvotes: 1

schtever
schtever

Reputation: 3250

So you can't call in a single thread the methods log1 and log2 at the same time? But if the synchronized wasn't on the class object you could?

To be precise, you can't call the methods log1 and log2 in different threads at the same time. Declaring a method static synchronized has the same effect as synchronizing on the class object.

Here's an example where the second method synchronizes on the log variable instead of the class.

public class MyClass {

  public static synchronized void log1(String msg1, String msg2){
    log.writeln(msg1);
    log.writeln(msg2);
  }

  public static void log2(String msg1, String msg2){
    synchronized(log){
      log.writeln(msg1);
      log.writeln(msg2);  
    }
  }

}

In this case, two separate threads could execute log1 and log2 simultaneously because they synchronize on different objects: log1 on the MyClass.class object, and log2 on the log object (wherever that is defined).

Here's the key thing to remember about synchronized methods and blocks:

  1. The synchronized code has to synchronize using the same object instance across all threads.
  2. Classes are objects too! There's typically just one instance of a given Class's object, created when the class is first loaded.

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 691635

No. The two methods are both synchronized on MyClass.class. So if one thread calls any of the methods, another thread can't call any of those two methods at the same time.

If one method synchronizes on another object, then the two methods aren't mutually exclusive anymore, and one thread can call log2 while another thread calls log1.

Upvotes: 1

Related Questions