Java同步和对象锁

3
假设我有两个线程。 线程1正在访问同步方法,同时,线程2正在访问同一对象的另一个同步方法。 据我所知,线程2应等待线程1完成其任务。 我的问题是,线程2是否在对象的等待线程列表中? 对我来说似乎是这样,但线程2没有调用wait()方法,那么作为逻辑结果,它不应该在对象的等待线程列表中。 如果它不在对象的等待线程列表中,那么线程2的状态是什么?
2个回答

2
当Tread2等待Thread1释放Thread1持有的内在锁时,它会被阻塞,直到内在锁变为可用状态(即被执行线程Thread1释放)。所以,简而言之,Thread2正在等待锁被释放,以便可以获取它。
现在,当一个线程调用wait()时,它必须已经持有内在锁。调用wait()会释放锁,并将线程置于等待状态,等待来自notify()或notifyAll()的信号以继续执行。
因此,这两种情况是不同的,前者是隐式地被阻塞,直到资源(锁)变得可用。而后者则是显式地释放已经持有的锁,然后等待信号,以便重新获取锁并继续执行。

0

这两种情况之间有所区别,您注意到了这一点。

当线程尝试运行一个synchronized块时,但是其他线程持有监视器的锁时,传入的线程会被阻塞,直到锁被释放并授予它。

要让线程调用wait(),它必须已经持有监视器的锁(这是一个相关的区别)。此外,调用wait()会使线程等待(释放锁),通常直到某个其他线程通知它。

通常上面应该是总是,在理想情况下是如此,但是正如Java文档中指定的那样,可能会发生称为虚假唤醒的现象,使等待线程因没有明显的原因而唤醒。这就是为什么等待条件应该包含在while语句中而不是if语句中的原因。例如:

synchronized (this) {
    while (x < 0) { wait(); }
}

不要:

synchronized (this) {
    if (x < 0) { wait(); }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接