Synchronization Questions

Okay this probably isn’t the right spot for this post, but it should be close enough given that synchronization can be a major part of networking if threads are used.

I have a few questions regarding the actual key word.

These are specific questions for the most part, I tried looking at some tutorials online, but they were worded in such a way that i was unsure what they were trying to tell me.

1. If a class has a few synchronized methods eg:


class A
{
  public void synchronized a()
  {
       //code here
  }
  
  public void synchronized b()
  {
       //code here  
  }

}

a.As they are non static methods, if one thread calls a, and another thread calls b, will one of the threads wait until the other method is complete, or does this synchronization only work on a method by method basis, eg If two threads call “a” one will wait, but they if they each call different methods they will not wait?
bHow about for static methods?

2For the following code:


class A
{
  public void a()
  {
       synchronized(this)
       {
         //code here 
         b();
       }
  }
  
  public void b()
  {
     synchronized(this)
       {
         //code here 
       }
  }
}

Will the synchronized statement be smart enough to realize that the object is already locked by the same thread and continue executing? (That is if method a is called, although method b also locks the object, the same thread already has a lock in place).

Now I already have a few guesses and I was just planning on having all class methods that need to be called be synchronized methods and all class methods they needed to call be non synchronized and private, and rely on the public method synchronization, but I’d like to know exactly how this statement works before I try to take advantage of it.

Also if anyone has a really indepth tutorial link that goes in detail on the topic I would appreciate it.

synchronized (an object) {}
… synchronizes on object of course…
when you have synchronized in method name it synchronizes on object of that method, equivalent to synchronized (this) {}. Synchronizing on static methods probably just (never did it :slight_smile: ) synchronizes on class object, equivalent to synchronized (getClass()) {}

Edit: deleted wrong informations, sorry for that :slight_smile:

First, a little background: When a thread enters a synchronized block, it acquires the lock of some object (think of it as a mutex). When a thread attempts to acquire a lock, it will fail if another thread currently holds the same lock. Every Java object has a lock, so any object can be used to synchronize on.

Non-static synchronized methods all synchronize on the object owning the method. In other words, it’s the same as wrapping the entire method in a synchronized(this) block. So when a synchronized method is entered, the lock to the owning object is acquired. Another thread calling any of the methods on that object while the lock is held will block until the first thread releases it. So one thread will wait for the lock to be released if both call “a” of if they both call different methods.

[quote]bHow about for static methods?
[/quote]
For synchronized static methods, the lock of the class object is acquired. So once again, multiple threads calling multiple static methods in the same class will still be synchronizing on one object, which means that only one thread can call any of the methods at a time.

When a thread attempts to acquire a lock that it already holds, success is automatic. So yes, a single thread can call multiple synchronized methods in the same object. If that were not possible, synchronized methods would hardly be useful.

[quote]Also if anyone has a really indepth tutorial link that goes in detail on the topic I would appreciate it.
[/quote]
I don’t know of any good tutorials online, but there are some good books out there. Java Concurrency in Practice is an excellent reference that covers a great deal more that you need to know besides synchronization blocks.

In my own code, I very rarely use synchronized methods or synchronize on this. As a general rule of thumb, it’s a good idea to minimize the amount of work you do in a synchronized block and to synchronize at the lowest level possible. A trivial example:


class MyClass {
    List<MyOtherClass> theList;
    
    void addSomethingToList(MyOtherClass obj) {
        synchronized(theList) {
            theList.add(obj);
        }
    }

    void doSomethingToAnObjectFromList(int index) {
        MyOtherClass obj = null;
        synchronized(theList) {
            obj = theList.get(index);
        }
        if(obj != null) {
            obj.doSomething();
        }
    }
}

The idea is that you don’t want to needlessly prevent a thread from carrying out operations that don’t need to be synchronized, or to make a thread wait longer than it needs to. Consider what might happen if both methods in this example were synchronized: a thread calling doSomethingToAnObjectFromList would acquire the lock on the instance of MyClass and hold it until the method returns, meaning the call to obj.doSomething would be in the synchronization block. This means that any other threads calling addSomethingToList will needlessly be waiting for obj.doSomething to complete. Things really get bad if obj.doSomething is a lengthy operation. So by locking only on theList (i.e. the lowest level), you ensure that only the bits that need to be synchronized actually are and no threads will be waiting for obj.doSomething to complete.

Sometimes it really does make sense to synchronize entire methods, or on this, but most of the time you probably don’t need to.

synchronised static methods :’( :’( :’( :’( :’(

Please don’t ever do this. If you need to synchronise a static method there is most likely a problem with your design. The only time I can think of off the top of my head is if you are doing a get on a singleton that is lazily initialised.

The smaller the time you make the lock for the better, only do it for critical regions, otherwise performance will suffer.

Thanks everyone for your help, this pretty much clears everything I wanted to know.

Regarding the static methods, I was just curios and wasn’t really planning on using that, I’d just like to know how it would behave. Also from the general opinion, It looks like i should probably try to do some more careful synchronization rather then synchronize the whole method for optimization purposes.

Thanks again!