tags:

views:

61

answers:

1

I have a Java application using threads, which uses several Lock object instances to synchronize access to common resources.

Now as part of a performance measurement I want to measure the time spent by each thread in every lock. I have tried so far NetBeans profiler.

Netbeans profiler shows me the total wait time for a thread but it is impossible to know how much time in which lock the thread waited.

Which tool will you recommend for this kind of measurement?

Cheers

+1  A: 

Depending on exactly what data you need, you can just get this information from within your Java program. For example, something like this will sample held locks 20 times a second for 100 seconds, creating effectively a map of lock > approximate time locked (number of "ticks" during which the given lock was being locked on):

private static void runProfile() {
    try {
        final int noSeconds = 100;
        final int sleepMillis = 50;
        final int noSamples = noSeconds * 1000 / sleepMillis;

        ThreadMXBean thb = ManagementFactory.getThreadMXBean();
        Map<String,Integer> blockCounts = new HashMap<String, Integer>(50);
        for (int i = 0; i < noSamples ; i++) {
            long[] ids = thb.getAllThreadIds();
            ThreadInfo[] infs = thb.getThreadInfo(ids, 0);
            for (ThreadInfo ti : infs) {
                LockInfo lockInf = ti.getLockInfo();
                if (lockInf != null) {
                    String key = lockInf.toString();
                    Integer cnt = blockCounts.get(key);
                    blockCounts.put(key, cnt == null ? 1 : cnt+1);
                }
            }

            Thread.sleep(sleepMillis);
        }

        System.out.println("Locks:");
        for (String lockName : blockCounts.keySet()) {
            System.out.println(lockName + " : " + blockCounts.get(lockName));
        }
    } catch (InterruptedException iex) {
        Thread.currentThread().interrupt();
    }
}

Adapt to collect the data as you need it.

You can then start this going in a background thread e.g.:

    Thread thr = new Thread() {
        public void run() {
            runProfile();
        }
    };
    thr.setPriority(Thread.MAX_PRIORITY-1);
    thr.start();
Neil Coffey
@Neil thanks for answering, I guess this is the only way to do it then. I want to do this outside the running process though. Is it possible? Frankly I have no experience with using the new Management APIs. A little more nudge/links will be good as to how to do it from another JVM. Cheers
Elister