views:

181

answers:

3

Is there any way to check how many threads are waiting for a synchronized method to become unlocked?

I would like to know when the thread calls a synchronized method:

1) How many threads are already waiting to call the method?

2) Once the method is called how long it needed to wait for the method to become unlocked?


Solution: I solved this using stackers answer:

public class LockedClass {
    public static int count;
    public static void measuringClass() throws IOException{
        long startTime = System.currentTimeMillis();
        count++;
        System.out.println("Threads waiting="+count);
        lockedMethod(startTime);
        count--;
        System.out.println("Threads waiting="+count);
    }
    public static synchronized void lockedMethod(long startTime) throws IOException{
        System.out.println("I spent="+(System.currentTimeMillis()-startTime)+" in the queue");
        Hashtable<String, String> params = new Hashtable<String, String>();
        params.put("param1", "test");
        params.put("param2", "12345678");
        String sessionId = Common.getSession(Common.executeHttpRequest(params));
    }
}
+3  A: 

1) I do not believe it's possible to have this level of visibility in your code. Java provides a more powerful concurrency API which provides much more direct control and visibility. As a starting point, there's a class Semaphore which has a method getQueueLength() which sounds like it might be what you want.

2) When a synchronized method is called, the calling thread will wait until the method is unlocked, how long that takes depends on how long the code with the lock takes to do its thing. When wait()-ing on an object, you can specify a timeout. I don't believe you can do that with a synchronized method.

Brabster
+1. I'd say `ReentrantLock` is more suitable in this case than a `Semaphore` though.
Enno Shioji
+1  A: 

I think Java Thread Validator may provide some insight into these questions.

It doesn't give exactly those stats, but it does tell you how often contention happens and what the wait time is etc.

Stephen Kellett
A: 

You could transform your code to use a synchronized block instead of synchronized methods, here is my rough draft. I'm not sure whether it matches you second requirement (due to my choppy english)

public class Sync {
    public static int waiting = 0;
    private Object mutex = new Object();

    public void sync() {
        waiting++;
        synchronized (mutex) {
            waiting--;
            long start = System.currentTimeMillis();
            doWhatever();
            System.out.println("duration:"
                    + (System.currentTimeMillis() - start));
        }
    }
}
stacker
Thanks, I used a variation of this to achieve what I wanted
MontyBongo
Hate to -1, but you have a race condition with `waiting++;` there... And inter-thread visibility is also not ensured. This could cause indeterminable behavior and is not good. I recommend Brabster's answer (not the Semaphore though, but this one: http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html#getQueueLength%28%29)
Enno Shioji