我正在尝试断言是否使用LockSupport.park(Object blocker)来实现拦截器的监视器锁对象。也就是说:如果在blocker上同步的部分中调用,会释放blocker的监视器锁吗?
这是我做的一个junit测试让我觉得是这样的。
我知道线程处于状态WAITING状态,这是调用Òbject.waitor LockSupport.park()的结果,在我看来,这种调用使用的是相同的底层机制。但是,javadoc没有明确地澄清我的问题,所以我不确定。
final Object blocker = new Object();
final Thread thread = new Thread() {
@Override
public void run() {
synchronized(blocker) {
while(!interrupted()) {
assertTrue(holdsLock(blocker));
LockSupport.park(blocker);
}
}
}
};
try {
thread.start();
while(thread.getState() != Thread.State.WAITING)
Thread.sleep(100);
assertEquals(0, ManagementFactory.getThreadMXBean().getThreadInfo(thread.getId()).getLockedMonitors().length);
} finally {
thread.interrupt();
}发布于 2014-01-27 08:25:14
如果javadoc没有定义行为,则它是未定义的;)
别指望它做任何事。
发布于 2014-01-27 14:48:57
答案很简单:不。LockSupport并不适用于一般的应用程序编程。由于没有任何保护(正如同步等待/通知所提供的那样),所以需要对整个线程环境进行显式控制。也就是说,您不能使用第三方软件并期望它符合您的标准。
关于如何使用park/unpark的一个很好的示例,请查看ForkJoinPool的源代码。
发布于 2018-08-09 15:00:53
首先,您的代码存在缺陷,只需使用:
ManagementFactory.getThreadMXBean().getThreadInfo(thread.getId())正如它在文档中所说的(它说这个方法相当于调用getThreadInfo(id, 0),后者说)
..。不获取线程的锁定监视器和锁定同步器。
所以这个数组总是零长度。
所以如果你想要明智之举的话:
public class DeleteMe3 {
public static void main(String[] args) {
Object lock = new Object();
System.out.println(lock.toString());
Thread thread = new Thread() {
@Override
public void run() {
synchronized (lock) {
boolean holdLock = Thread.holdsLock(lock);
if (!holdLock) {
throw new AssertionError("Does not hold lock");
} else {
System.out.println("I hold the lock");
}
System.out.println("Before parking");
LockSupport.park(lock);
}
}
};
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
showIfAnyLocksHeld(thread.getId());
System.out.println("Unparking... ");
LockSupport.unpark(thread);
}
private static void showIfAnyLocksHeld(long threadId) {
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] infos = bean.getThreadInfo(new long[] { threadId }, true, true);
if (infos.length == 0) {
System.out.println("Thread we are interested in has died");
return;
}
MonitorInfo[] mInfos = infos[0].getLockedMonitors();
if (mInfos.length == 0) {
System.out.println("No locks held by thread " + threadId);
return;
}
System.out.println("Thread with id = " + threadId + " holds lock(s) : " +
Arrays.stream(mInfos).map(MonitorInfo::toString).collect(Collectors.joining(" ; ")));
}
}输出将包括:
java.lang.Object@5f2108b5
I hold the lock
Before parking
Thread with id = 12 holds lock(s) : java.lang.Object@5f2108b5因此,您可以看出,LockSupport.park将而不是释放锁;但是如果它释放了锁,则会很奇怪;除非它会被这样记录下来,而它没有这样做。
https://stackoverflow.com/questions/21375940
复制相似问题