在工作線程死亡之前,我打電話給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