0

Possible Duplicate:
What is the difference between synchronized and static synchronized?

What is the advantage having object lock over class lock?

For example,

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

and,

public void log2(String msg1, String msg2){
       synchronized(this){
          log.writeln(msg1);
          log.writeln(msg2);
       }
    }
Community
  • 1
  • 1
FrankD
  • 859
  • 4
  • 19
  • 31

3 Answers3

1

If you create a lock on the class, then all instances of the class will share the lock. If you have 1 instance, there won't be any difference. If you have thousands of instances, they will all use the very same lock. If many threads try to acquire the lock at the same time, they will block each other out. In the worst case, this can cause your code to behave as if there were no threads at all.

If you create the lock on the instance, then several threads can execute the protected code as long as they operate on different instances. Here, the threads don't block each other. So this approach performs better.

But that's not what you need to ask. The real question is: What kind of lock do I need?

If you want to make sure only a single thread can write to the log, you should synchronize on log. This approach has the additional advantage that it will automatically work correctly when you start using several log files (say, one per thread).

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
0

They are not inter-changable as they lock on different objects.

If locking on the object is approriate, use that. If you want to lock on a class (which is unlikely) you would use that.

I would consider this combination.

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

This will ensure the object is not being modified and the lines appear together in the logs.

However since the log2 doesn't appear to be using mutable fields you can use

private final Log log = ...

public void log2(String msg1, String msg2){
    synchronized(log) {
        log.writeln(msg1);
        log.writeln(msg2);
    }
}
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

From the Logger class given below, if the Log class were modified to use Lock object(s) the threads that call log(String msg1, String msg2) would perform operations on the thread-safe Log using its new synchronization policy. But threads that call the log(String msg1) method would always synchronize on the Log instance and all the Lock objects(s) in the Log class would be held at one time. In such a condition the implementation of Logger would break. That is why it is recommended to use private final Lock objects or the Lock class instead of client-side locking.

public class Logger {
    private final Log log;
    private final Object lock = new Object();

    public Logger(Log log) {
        this.log = log;
    }

    public void log(String msg1) {            // log synchronizes on log instance
        synchronized (log) {        
            log.writeln(msg1);      
        }
    }

    public void log(String msg1, String msg2) {   // log uses private final lock
        synchronized (lock) {
            log.writeln(msg1);
                        log.writeln(msg2);  
        }
    }   
}
clinton
  • 612
  • 3
  • 6