views:

1130

answers:

3

I have a class which looks something like this:

public class Test {

private static final Object someObject = new Object();

public void doSomething()
{
 synchronized (someObject) {
  System.out.println(someObject.toString());
 }
}

}

Can I consider the object to be synchronized, or is there a problem since it is a static member?

Edit: note that different threads might be accessing doSomething() and the object must be accessed in a thread-safe manner in that case.

+5  A: 

By using a static object as your monitor object, only one thread using ANY instance of the Test class can get into the sync block. If the monitor object was not a static object, other threads holding different instances of the Test class could get into the sync block.

David M. Karr
I do not understand. Does this mean the code snippet works like I am expecting it?
Yuval A
Yes, it works as expected
Guillaume
I believe David's point is that by making it a static member, it introduces a possibility of a bottleneck, if lots of threads are expected to call that method.
Chris Jester-Young
+4  A: 

Here someObject is acting as a lock (monitor) for all objects of type Test. That is, if doSomething() is invoked on two separate instances of Test, one will block before the other completes. This is different from a synchronized method which which is mostly equivalent to the code above with someObject replaced by this.

Changing someObject to non-static will result in per--instance locking. This is essentially the "private lock object" idiom as described in item 70 of Effective Java.

Dave Ray
A: 

A common pattern for getting a class-specific instance-independent lock like this is to use the Class object itself:

public class Test {
  public void doSomething() {
    synchronized (Test.class) {
      // something
    }
  }
}

which is effectively what a synchronized static method does. Of course if you want more than one lock like this, you'll need to declare them as static fields as in your example.

Alex Miller