当前位置: 首页 > 面试题库 >

几个线程可以在Java的同一监视器上保持锁吗?

沃宇
2023-03-14
问题内容

当前,我们正在分析tomcat线程转储。在tomcat上同时运行的所有线程的单线程转储包含以下行:

...
"soldOutJmsConsumerContainer-1" prio=10 tid=0x00007f8409c14800 nid=0x231 in Object.wait() [0x00007f8403a9f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:485)
    at com.tc.object.RemoteObjectManagerImpl.waitUntilRunning(RemoteObjectManagerImpl.java:150)
    at com.tc.object.RemoteObjectManagerImpl.basicRetrieve(RemoteObjectManagerImpl.java:216)
    - locked <0x00007f847612c820> (a com.tc.object.RemoteObjectManagerImpl)
...
"catalina-exec-33" daemon prio=10 tid=0x0000000041bc4000 nid=0x832 in Object.wait() [0x00007f8400f73000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:485)
    at com.tc.object.RemoteObjectManagerImpl.waitUntilRunning(RemoteObjectManagerImpl.java:150)
    at com.tc.object.RemoteObjectManagerImpl.basicRetrieve(RemoteObjectManagerImpl.java:216)
    - locked <0x00007f847612c820> (a com.tc.object.RemoteObjectManagerImpl)
...
"catalina-exec-109" daemon prio=10 tid=0x0000000041469800 nid=0x1e87 in Object.wait() [0x00007f83f84c1000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:485)
    at com.tc.object.RemoteObjectManagerImpl.waitUntilRunning(RemoteObjectManagerImpl.java:150)
    at com.tc.object.RemoteObjectManagerImpl.basicRetrieve(RemoteObjectManagerImpl.java:216)
    - locked <0x00007f847612c820> (a com.tc.object.RemoteObjectManagerImpl)

特别是我们不明白

- locked <0x00007f847612c820> (a com.tc.object.RemoteObjectManagerImpl)

根据我们的理解,它说三个线程当时正在锁定同一监视器。根据我们的理解,根据JLS,这是不可能的。

我们对线程转储的解释正确吗?


问题答案:

看起来所有这些线程都在等待与监视器关联的条件,即它们称为wait()该监视器的方法。

当线程wait()在其拥有的监视器上调用时,它会临时释放监视器,并在从返回时需要重新获取它wait()。因此,您可以拥有多个线程,这些线程曾经拥有一个监视器,但是现在正在等待wait()方法。



 类似资料:
  • 两个线程在同一个监视器上等待,例如,如果一个线程调用等待锁,而另一个获取监视器的线程在通知第一个线程之前也调用等待。现在两个线程都在等待,但是没有人得到通知。我该怎么称呼这种情况?这能叫僵局吗? 编辑:假设只有这两个线程,并且无法从其他地方通知它们 更新:我刚刚创建了我在问题中描述的情况。当转换器线程在侦听器线程之前启动时,以下代码大部分时间都正常工作。然而,当我在changer之前启动liste

  • 问题内容: 线程都是可运行的,并且它们拥有相同的锁。两个线程都可以运行时,它们可以锁定相同的地址吗?那是JRE错误吗? 问题答案: 该问题仅存在于线程转储中。实际上,在任何时间点,锁都仅由一个线程持有。但是,线程转储显示两个具有相同锁的不同线程,因为它不是原子的。 可以使用以下程序轻松重现该行为:

  • 问题内容: 我一直在弄乱Java中的线程来处理它们(这似乎是最好的方法),现在了解了sync,wait()和notify()的情况。 我很好奇是否有一种方法可以同时对两个资源进行wait()。我认为以下内容并不能完全满足我的想法( 编辑 : 请注意,此示例中省略了通常的while循环,仅专注于释放两个资源 ): 在这种(非常人为)情况下,将保留token2直到返回token1,然后将保留token

  • Java SE6文档中的ThreadPoolExecutor类具有以下方法: 返回正在积极执行任务的线程的大致数目。 这里近似和积极执行是什么意思? 在调用之前、期间和之后,是否保证 null 我已经研究了线程池执行器监视需求,以及如何在java中判断线程池中是否有可用的线程,但它们没有回答我的查询。

  • 问题内容: Java VM可以支持多少个线程?这会因供应商而异吗?通过操作系统?其他因素? 问题答案: 这取决于您正在使用的CPU,操作系统,其他正在执行的操作,您正在使用的Java版本以及其他因素。我已经看到Windows服务器在关闭计算机之前具有> 6500个线程。当然,大多数线程没有做任何事情。一旦计算机遇到了大约6500个线程(使用Java),整个计算机就会开始出现问题并变得不稳定。 我的

  • 我做了几个线程转储,发现有16个线程在等待同一个锁,例如: “__ejb-thread-pool1”守护进程prio=6 tid=0x39657c00 nid=0x1c08在条件[0x3297f000]java.lang.thread.state:waiting(parking)在sun.misc.unsafe.park(本机方法)-在java.util.concurrent.locks.lock