在工作线程死亡之前,我打电话给threadInfo.getBlockedCount()
和getBlockedTime()
。 我得到的阻塞计数为1,但阻塞时间为0. 这是否意味着线程被阻塞,但阻塞的时间少于一毫秒?java多线程应用程序:正在线程阻塞时间
如果以上情况属实,是否有另一种方法可以获得线程被阻塞的准确时间?
在工作线程死亡之前,我打电话给threadInfo.getBlockedCount()
和getBlockedTime()
。 我得到的阻塞计数为1,但阻塞时间为0. 这是否意味着线程被阻塞,但阻塞的时间少于一毫秒?java多线程应用程序:正在线程阻塞时间
如果以上情况属实,是否有另一种方法可以获得线程被阻塞的准确时间?
是的,这意味着它被阻止了0毫秒。即不涉及阻塞。该线程没有等待监视器锁进入同步块/方法。
你看到了这一点,因为你必须写一个简单的程序与一个或两个线程,并没有延迟。 您将需要在线程上产生真正沉重的负载以实际看到正值。
显然,这就是它的意思,显然没有办法让时间更精确。 (javadocs说阻塞的时间可能是,测量值为,并且(可能)以更高的精度累积,但ThreadInfo API不公开此信息,并且似乎没有任何其他犹太人获得它的方法。)
我说“很明显”,因为javadoc实际上将时间值描述为“大约累计经过时间”。这留下了可能性,这可能是一个非常粗略的近似值,可能与System.getCurrentTimeMillis()
返回的时钟值具有相同的粒度。此外,它并不会说如果用高精度计时器测量的累计时间在转换为毫秒值时会被舍入或截断;即零是指“小于1毫秒”还是“小于0.5毫秒”。
可以试一下,喜欢的东西:
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
public class BlockedTimeMain {
public static void main(String[] _) throws InterruptedException {
ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
mbean.setThreadContentionMonitoringEnabled(true);
final Object lock = new Object();
Thread t = new Thread("Foo") {
@Override public void run() {
// This will block forever
synchronized(lock) {
// Will never get here
System.out.println("Got the lock from " + Thread.currentThread());
}
}
};
synchronized(lock) {
t.start();
for (;;) {
ThreadInfo[] tis = mbean.getThreadInfo(new long[]{t.getId()}, true, true);
ThreadInfo ti = tis[0];
if (ti.getThreadId() != t.getId())
throw new AssertionError("Unexpected " + t.getId() + " vs " + tis[0].getThreadId());
System.out.println(t + " " + ti.getThreadState()
+ ": blockedTime=" + ti.getBlockedTime() + "/" + ti.getBlockedCount()
+ ", waitTime" + ti.getWaitedTime() + "/" + ti.getWaitedCount());
Thread.sleep(1000);
}
}
}
}
样本输出:
Thread[Foo,5,main] BLOCKED: blockedTime=2/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=1007/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=2012/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=3016/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=4021/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=5025/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=6028/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=7032/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=8035/1, waitTime0/0
然而,一个线程(被阻塞),阻塞时间似乎只返回一个非零如果在启动线程之前调用ThreadMXBean#setThreadContentionMonitoringEnabled(true),则返回结果。否则,它总是返回零(如果争用监视被禁用,则返回-1)。
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
public class BlockedTimeMain {
public static void main(String[] _) throws InterruptedException {
ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
final Object lock = new Object();
Thread t = new Thread("Foo") {
@Override public void run() {
// This will block forever
synchronized(lock) {
// Will never get here
System.out.println("Got the lock from " + Thread.currentThread());
}
}
};
synchronized(lock) {
t.start();
mbean.setThreadContentionMonitoringEnabled(true);
for (int i=0; i < 5; i++) {
ThreadInfo[] tis = mbean.getThreadInfo(new long[]{t.getId()}, true, true);
ThreadInfo ti = tis[0];
if (ti.getThreadId() != t.getId())
throw new AssertionError("Unexpected " + t.getId() + " vs " + tis[0].getThreadId());
System.out.println(t + " " + ti.getThreadState()
+ ": blockedTime=" + ti.getBlockedTime() + "/" + ti.getBlockedCount()
+ ", waitTime" + ti.getWaitedTime() + "/" + ti.getWaitedCount());
Thread.sleep(1000);
}
}
System.exit(0);
}
}
样本输出:下面演示该代码
Thread[Foo,5,main] BLOCKED: blockedTime=0/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=0/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=0/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=0/1, waitTime0/0
请将此更改为'System.currentTimeMillis的()'。 – asgs 2011-03-25 03:19:16