首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LockSupport.park(对象)是否释放拦截器对象的监视锁?

LockSupport.park(对象)是否释放拦截器对象的监视锁?
EN

Stack Overflow用户
提问于 2014-01-27 08:21:44
回答 3查看 678关注 0票数 1

我正在尝试断言是否使用LockSupport.park(Object blocker)来实现拦截器的监视器锁对象。也就是说:如果在blocker上同步的部分中调用,会释放blocker的监视器锁吗?

这是我做的一个junit测试让我觉得是这样的。

我知道线程处于状态WAITING状态,这是调用Òbject.waitor LockSupport.park()的结果,在我看来,这种调用使用的是相同的底层机制。但是,javadoc没有明确地澄清我的问题,所以我不确定。

代码语言:javascript
复制
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();
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-01-27 08:25:14

如果javadoc没有定义行为,则它是未定义的;)

别指望它做任何事。

票数 0
EN

Stack Overflow用户

发布于 2014-01-27 14:48:57

答案很简单:不。LockSupport并不适用于一般的应用程序编程。由于没有任何保护(正如同步等待/通知所提供的那样),所以需要对整个线程环境进行显式控制。也就是说,您不能使用第三方软件并期望它符合您的标准。

关于如何使用park/unpark的一个很好的示例,请查看ForkJoinPool的源代码。

票数 2
EN

Stack Overflow用户

发布于 2018-08-09 15:00:53

首先,您的代码存在缺陷,只需使用:

代码语言:javascript
复制
ManagementFactory.getThreadMXBean().getThreadInfo(thread.getId())

正如它在文档中所说的(它说这个方法相当于调用getThreadInfo(id, 0),后者说)

..。不获取线程的锁定监视器和锁定同步器。

所以这个数组总是零长度。

所以如果你想要明智之举的话:

代码语言:javascript
复制
   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(" ; ")));
    }

}

输出将包括:

代码语言:javascript
复制
 java.lang.Object@5f2108b5
 I hold the lock
 Before parking
 Thread with id = 12 holds lock(s) : java.lang.Object@5f2108b5

因此,您可以看出,LockSupport.park而不是释放锁;但是如果它释放了锁,则会很奇怪;除非它会被这样记录下来,而它没有这样做。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21375940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档