Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Block level synchronization

What is the significance of parameter passed to synchronized?

synchronized ( parameter )
{

}

to achieve block level synchronization. Somewhere i saw code like

class test
{
    public static final int lock =1;

    ...

    synchronized(lock){
       ...
    }
}

I don't understand the purpose of this code.

Can anyone give me a better example and/or explain it?

like image 844
Madan Avatar asked May 17 '09 18:05

Madan


2 Answers

It's the reference to lock on. Basically two threads won't execute blocks of code synchronized using the same reference at the same time. As Cletus says, a synchronized method is mostly equivalent to using synchronized (this) inside the method.

I very much hope that the example code you saw wasn't quite like that - you're trying to synchronize on a primitive variable. Synchronization only works on a monitor (via a reference) - even if it were legal code, x would be boxed, which would lead to some very odd behaviour, as some integers will always be boxed to the same references, and others will create a new object each time you box. Fortunately, the Java compiler realises this is a very bad idea, and will give you a compile-time error for the code you've posted.

More reasonable code is:

class Test
{
    private static final Object lock = new Object();

    ...

    synchronized(lock){
       ...
    }
}

I've made the lock private, and changes its type to Object. Whether or not it should be static depends on the situation - basically a static variable is usually used if you want to access/change static data from multiple threads; instance variables are usually used for locks when you want to access/change per-instance data from multiple threads.

like image 161
Jon Skeet Avatar answered Sep 21 '22 10:09

Jon Skeet


This:

public synchronized void blah() {
  // do stuff
}

is semantically equivalent to:

public void blah() {
  synchronized (this) {
    // do stuff
  }
}

Some people don't like to use 'this' for synchronization, partly because it's public (in that the instance is visible to external code). That's why you end up with people using private locks:

public class Foo
  private final static String LOCK = new String("LOCK");

  public void blah() {
    synchronized (LOCK) {
      // do stuff
    }
  }
}

The benefit is that LOCK is not visible outside the class plus you can create several locks to deal with more fine-grained locking situations.

like image 26
cletus Avatar answered Sep 21 '22 10:09

cletus