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

Java线程转储:“等待锁定”与“停放等待”之间的区别?

韶宏邈
2023-03-14
问题内容

在Java线程转储中,您可以看到堆栈跟踪中提到的锁。
似乎有三种信息:

1:

- locked <0x00002aab329f7fa0> (a java.io.BufferedInputStream)

2:

- waiting to lock <0x00002aaaf4ff6fa0> (a org.alfresco.repo.lock.LockServiceImpl)

3:

- parking to wait for  <0x00002aaafbf70bb8> (a java.util.concurrent.SynchronousQueue$TransferStack)
  • 1:线程已获得对象0x00002aab329f7fa0的锁。
  • 2&3:似乎是说线程正在等待该对象上的锁可用…
    但是2和3有什么区别?

问题答案:

使用内在锁时,您将在线程转储中获得“等待锁”,而使用java.util.concurrent中的锁时,将获得“停放以等待”。考虑以下示例

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockTest {

    final Lock lock = new ReentrantLock(true);

    synchronized void intrinsicLock() {
        Thread th = new Thread(new Runnable() {
            public void run() {
                intrinsicLock();
            }
        }, "My thread");
        th.start();
        try {
            th.join();
        } catch (InterruptedException e) {
        }
    }

    void reentrantLock() {
        lock.lock();
        Thread th = new Thread(new Runnable() {
            public void run() {
                reentrantLock();
            }
        }, "My thread");
        th.start();
        try {
            th.join();
        } catch (InterruptedException e) {
        }
        lock.unlock();
    }


    public static void main(String[] args) {
        LockTest lockTest = new LockTest();
        lockTest.intrinsicLock();
        //lockTest.reentrantLock();
    }

}

随着lockTest.intrinsicLock()您将获得以下线程转储:

"My thread" prio=10 tid=0x00007fffec015800 nid=0x1775 waiting for monitor entry [0x00007ffff15e5000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at LockTest.intrinsicLock(LockTest.java:9)
    - waiting to lock <0x00000007d6a33b10> (a LockTest)
    at LockTest$1.run(LockTest.java:11)
    at java.lang.Thread.run(Thread.java:662)

同时lockTest.reentrantLock()产生:

"My thread" prio=10 tid=0x00007fffec082800 nid=0x17e8 waiting on condition [0x00007ffff14eb000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007d6a33d30> (a java.util.concurrent.locks.ReentrantLock$FairSync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:842)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1178)
    at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:201)
    at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
    at LockTest.reentrantLock(LockTest.java:22)
    at LockTest$2.run(LockTest.java:25)
    at java.lang.Thread.run(Thread.java:662)


 类似资料:
  • 问题内容: 我有以下情况: 为了运行算法,我必须运行多个线程,并且每个线程都会在死之前设置一个实例变量x。问题是这些线程不会立即返回: 我应该使用等待通知吗?还是我应该嵌入一个while循环并检查是否终止? 感谢大家! 问题答案: 创建一些共享存储来保存每个线程的值,或者如果足够的话,只存储总和。使用a 等待线程终止。每个线程完成后都会调用,您的方法将使用该方法来等待它们。 编辑: 这是我建议的方

  • 问题内容: 之间有什么区别: 和 和 问题答案: 注意事项 : 这个答案仅涵盖了系列和系列之间的时序差异。。 为了这个答案的目的,我将使用一些示例方法: 是一个函数,它需要一个整数毫秒,并返回一个承诺,该承诺将在该毫秒后解析。 是一个函数,它需要一个整数毫秒,并返回一个承诺,该承诺将在该毫秒后被拒绝。 调用将启动计时器。在所有延迟完成后,可以使用等待一些延迟来解决,但请记住它们是同时执行的: 例子

  • 问题内容: 之间有什么区别: 和 和 问题答案: 注意事项: 这个答案仅涵盖了await系列和系列之间的时序差异Promise.all。请务必阅读@mikep的综合答案,其中也涵盖了错误处理方面更重要的区别。 出于此答案的目的,我将使用一些示例方法: res(ms) 是一个函数,它需要一个整数毫秒,并返回一个承诺,该承诺将在该毫秒后解析。 rej(ms) 是一个函数,它需要一个整数毫秒,并返回一个

  • 问题内容: 我想知道WebDriver等待超时和隐式等待超时之间的技术差异。 问题答案: 如文档中所述: 在内部设置将用于所有连续搜索的超时。如果找不到该元素,它将尝试在指定的时间内反复查找该元素。它仅执行此操作,不能强制执行其他任何操作- 它等待元素显示。 ,或者只是您用于特定搜索的一次计时器。它具有更大的可扩展性,意味着您可以将其设置为等待可能需要的任何条件。通常,您可以使用一些预构建的元素来

  • 嗨,我正在做一个项目,我已经达到了我非常困的部分。我试图寻找方法来学习如何在繁忙的等待中编写 while 循环,但我没有找到任何东西,我的代码只是作为无限循环运行。有人可以帮助我解释一个繁忙的等待循环应该如何工作,并帮助我打破这个无限循环吗? 该项目希望做到以下几点:早上,学生醒来后(这需要一段随机的时间),他会去洗手间为新的上学日做准备。如果浴室已经客满,学生需要Rest一下(使用yield()

  • 问题内容: 我正在为我的ubuntu服务器(针对我的多客户端匿名聊天程序)实现一种简单的线程池机制,并且需要使我的工作线程进入睡眠状态,直到需要执行一项工作(以函数指针和参数的形式) 。 我当前的系统即将关闭。我(工人线程正在)问经理是否有工作可用,以及是否有5毫秒没有睡眠。如果存在,请将作业添加到工作队列中并运行该函数。糟糕的循环浪费。 什么我 喜欢 做的是做一个简单的事件性的系统。我正在考虑有