java同步和对象锁

时间:2013-04-30 23:45:27

标签: java multithreading

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

2 个答案:

答案 0 :(得分:2)

当Tread2等待Thread1释放Thread1持有的内部锁时,其阻塞直到内部锁变为可用(如执行线程Thread1释放的那样)。因此,在夏天,Thread2正在等待释放锁,因此它可以获取它。

现在,当线程调用wait()时,它必须已经拥有内部锁。调用wait()然后释放锁,并将线程置于等待状态,等待来自notify()notifyAll()的信号继续执行。

因此,这两种情况是不同的,前者是关于执行隐式被阻止,直到资源(锁)变得可用。虽然后者是关于明确释放已经保持的锁定,然后等待其重新获取锁定并继续的信号。

答案 1 :(得分:0)

这两种情况之间存在差异,因为您需要注意。

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

对于要调用wait()的线程,它必须保持监视器的锁定(这是一个相关的区别)。 此外,调用wait()会使线程等待(释放锁定),通常是由某个其他线程通知

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

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

而不是:

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