我不完全理解wait
和notify
(object
)是如何工作的,因此我不得不将尝试缩减到以下代码部分。
main.java:
import java.util.ArrayList;
class Main
{
public static Main main = null;
public static int numRunners = 4;
public static ArrayList<Runner> runners = null;
public static void main(String[] args)
{
main = new Main();
}
Main()
{
runners = new ArrayList<Runner>(numRunners);
for (int i = 0; i < numRunners; i++)
{
Runner r = new Runner();
runners.add(r);
new Thread(r).start();
}
System.out.println("Runners ready.");
notifyAll();
}
}
runner.java:
class Runner implements Runnable
{
public void run()
{
try
{
Main.main.wait();
} catch (InterruptedException e) {}
System.out.println("Runner away!");
}
}
当前,我在调用main.main.wait();
时得到一个非法MonitorStateException,但我不明白为什么。从我所看到的情况来看,我需要同步runner.run
,但在这样做的时候,我假设它只会通知一个线程,而我的想法是通知所有线程。
我已经查看了java.util.concurrent
,但是我找不到合适的替换(也许我只是遗漏了一些东西)。
您同时调用了wait
和notifyall
而没有使用synchronized
块。在这两种情况下,调用线程必须拥有调用方法的监视器上的锁。
从notify
的文档(wait
和notifyall
具有类似的文档,但有关最完整的说明,请参阅notify
):
此方法只应由作为此对象的监视器所有者的线程调用。线程通过以下三种方式之一成为对象监视器的所有者:
一次只能有一个线程拥有对象的监视器。
在notifyall
之后,一次只有一个线程能够实际退出wait
,因为它们都必须再次获取相同的监视器--但所有线程都已被通知,因此一旦第一个线程退出同步块,下一个线程将获取锁等。
除非当前线程拥有对象的监视器,否则不能在对象上wait()
。为此,必须在其上synchronize
:
class Runner implements Runnable
{
public void run()
{
try
{
synchronized(Main.main) {
Main.main.wait();
}
} catch (InterruptedException e) {}
System.out.println("Runner away!");
}
}
同样的规则也适用于notify()
/notifyAll()
。
wait()
的Javadocs提到:
此方法只应由作为此对象的监视器所有者的线程调用。有关线程可以成为监视器所有者的方式的说明,请参阅notify
方法。
IllegalMonitorStateException
-如果当前线程不是此对象监视器的所有者。
并从notify()
:
线程通过以下三种方式之一成为对象监视器的所有者:
synchronized
语句的主体。class
类型的对象,通过执行该类的同步静态方法。问题内容: 我正在将程序从Java转移到Objective C,需要使用在Java中经常用于线程化的wait和notify方法,但似乎在Objective C中找不到任何等效的方法。我尝试使用NSLock对象,但是我没有认为它没有用。(我正在使用[NSLock锁定]进行等待,并使用[NSLock解锁]进行通知)我无法找到的Objective C中有什么等效项吗? 问题答案: 您可以使用多种技术。您
我想做一个小练习来习惯等待/通知。我想做的是简单地启动一个线程,然后用等待让它进入睡眠状态,用通知唤醒它,多次。 我的代码是: 我希望这会是这样 相反,这样做: 所以。。。通知似乎没有唤醒打印机线程? 这不应该是一个死锁,因为通过等待,我释放了所有的锁,所以主服务器不应该有任何对打印机的锁,打印机应该能够唤醒并打印。 我做错了什么?
问题内容: 我知道您可以使用lock在c#中锁定对象,但是可以放弃该锁并等待其他东西来通知您它已更改,就像您可以在Java中使用wait和notify一样吗? 在我看来,分别在Java和C#中同步和锁定是同义的。 问题答案: 等效功能(包括常规锁定)在Monitor类中。 C#中的语句等效于调用并带有适当的try / finally块。 有关更多详细信息,请参见我的线程教程或Joe Albahar
问题内容: 我写了一个永远不会停止的测试应用程序。它发出(是一个对象),但是我从不打电话通知。为什么此代码结束?尽管主线程在上同步,但生成的线程仍在运行,因此不会锁定该对象。 结果是主线程等待5秒钟,在此期间工作人员提供其输出。然后,在5秒钟后,程序退出。不等。如果主线程在5秒钟内没有进入睡眠状态(对此行进行了注释),则实际上将等到工作人员完成操作。当然,这里是一种使用方法,但是,出乎意料的是,它
我有一段代码 如您所见,我首先将标志设置为false,这样其中一个线程就可以进入Sum2Elements方法并将其更改为true,从而让所有人都等待。 我知道在同步代码中,只有一个线程可以完成它的任务,这里我有两个同步方法,这是否意味着两个线程在每次通知之后都在尝试执行这个方法? 如果是这样,那么一个线程是否不可能输入Sum2Elements,在另一个线程进入InsertElement之前将标志更
问题内容: 与传统的等待通知机制相比,使用Condition接口/实现的优点是什么?在这里,我引用道格·李(Doug Lea)的评论: 条件将对象监视方法(wait,notify和notifyAll)分解为不同的对象,从而通过与任意Lock实现结合使用,从而使每个对象具有多个等待集。如果Lock替换了同步方法和语句的使用,而Condition替换了Object监视器方法的使用。 我看到这是实现等待