Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does it seem to take a long time for this synchronized block to get a lock?

I am new to multi-threading in java, and I have a question some might find trivial.

I have to debug a third party piece of code and I need some basic information, to know where to look for the problem because the code is very large.

When the following code runs:

public void method()
{
   long startTime = System.currentTimeMillis();
   synchronized (obj)
   {
      log( "time:" + System.currentTimeMillis() - startTime + " ms" );
      ...
   }
}

I get:

11:13:12 - time: 3816 ms
...
11:14:14 - time: 0 ms

Why is taking so long (3816 ms) to get the lock for the object? Where should I look? For example, I would imagine a possible answer would be to look for code which acquires the lock for "obj" i.e. block such as:

synchronized (obj) { ... }

Or is it possible that any modification at the object "obj" without "synchronized" can also lock the object?

like image 710
dritan Avatar asked Mar 02 '15 17:03

dritan


Video Answer


1 Answers

If it takes a thread that long to obtain a lock, it's because someone else is currently holding it.

You should look for two things:

  1. Code blocks which synchronize on the same object or on other references to it (known as synchronized statements) :

    synchronized (obj) {
     ... 
    }
    
  2. Synchronized methods within the object itself.

    Say obj is of type MyObject, then you should look for methods such as these:

    public class MyObject{
        public synchronized void myMethod() {
         ...
        }
    }
    

    Because they are essentially the same as

    public class MyObject{
        public void myMethod() {
            synchronized (this) {
             ...
            }
        }
    }
    

    So if a thread is executing obj.myMethod(), threads that want to enter a synchronized (obj) block will have to wait, as they all lock on the same object. This, by the way, is the reason why I strongly recommend never using the synchronized method syntax, and always locking over a private (or protected) class member.

If another thread is currently executing code within such a block, the current thread will be locked out until the other thread finishes.

You can use jvisualvm's Threads tab or Jstack to take snapshots of the current execution state of all threads and the locks they're holding. If you're on android, see this answer on how to get a thread dump on there.

like image 153
Malt Avatar answered Oct 13 '22 17:10

Malt