package org.gridkit.jvmtool.stacktrace; import java.lang.Thread.State; import java.lang.management.ThreadInfo; import java.util.Arrays; import java.util.Iterator; public class ThreadCapture implements ThreadSnapshot { public long threadId; public String threadName; public long timestamp; public StackTraceElement[] elements; public CounterArray counters = new CounterArray(); public State state; @Override public long threadId() { return threadId; } @Override public String threadName() { return threadName; } @Override public long timestamp() { return timestamp; } @Override public StackFrameList stackTrace() { return new StackProxy(elements); } @Override public State threadState() { return state; } @Override public CounterCollection counters() { return counters; } public void copyFrom(ThreadInfo info) { threadId = info.getThreadId(); threadName = info.getThreadName(); elements = info.getStackTrace(); state = info.getThreadState(); if (info.getBlockedCount() > 0) { counters.set(ThreadCounters.BLOCKED_COUNTER, info.getBlockedCount()); } if (info.getBlockedTime() > 0) { counters.set(ThreadCounters.BLOCKED_TIME_MS, info.getBlockedTime()); } if (info.getWaitedCount() > 0) { counters.set(ThreadCounters.WAIT_COUNTER, info.getWaitedCount()); } if (info.getWaitedTime() > 0) { counters.set(ThreadCounters.WAIT_TIME_MS, info.getWaitedTime()); } } public void reset() { threadId = -1; threadName = null; timestamp = -1; elements = null; counters.reset(); state = null; } class StackProxy implements StackFrameList { StackTraceElement[] stack; public StackProxy(StackTraceElement[] stack) { this.stack = stack; } @Override public Iterator<StackFrame> iterator() { final Iterator<StackTraceElement> it = Arrays.asList(stack).iterator(); return new Iterator<StackFrame>() { @Override public boolean hasNext() { return it.hasNext(); } @Override public StackFrame next() { return new StackFrameWrapper(it.next()); } @Override public void remove() { it.remove(); } }; } @Override public StackFrame frameAt(int n) { return new StackFrameWrapper(stack[n]); } @Override public int depth() { return stack.length; } @Override public StackFrameList fragment(int from, int to) { throw new UnsupportedOperationException(); } @Override public StackFrame[] toArray() { StackFrame[] frames = new StackFrame[stack.length]; for(int i = 0; i != stack.length; ++i) { frames[i] = new StackFrameWrapper(stack[i]); } return frames; } @Override public boolean isEmpty() { return stack.length == 0; } } static class StackFrameWrapper extends StackFrame { StackTraceElement ste; public StackFrameWrapper(StackTraceElement ste) { super(ste); this.ste = ste; } @Override public StackTraceElement toStackTraceElement() { return ste; } } }