Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java notify()不';t唤醒对象。等待()_Java_Multithreading - Fatal编程技术网

Java notify()不';t唤醒对象。等待()

Java notify()不';t唤醒对象。等待(),java,multithreading,Java,Multithreading,我正在尝试使用用户“synchronized(object){object.wait()}”暂停我的服务器,直到对象准备就绪。我在将设置对象值的类中调用了“synchronized(object){object.notify()}”。但我的服务器似乎在wait()之后就再也不会醒来了 下面是我对设置对象值的调用 public class Action implements MouseInputListener, MouseMotionListener { .... publi

我正在尝试使用用户“
synchronized(object){object.wait()}
”暂停我的服务器,直到对象准备就绪。我在将设置对象值的类中调用了“
synchronized(object){object.notify()}
”。但我的服务器似乎在
wait()
之后就再也不会醒来了

下面是我对设置对象值的调用

public class Action implements MouseInputListener, MouseMotionListener {

    ....

    public void mouseClicked(MouseEvent e) {


        if (SwingUtilities.isLeftMouseButton(e)) {...
    }

        else {
            ....
            if(MyGame.currentPlayer == MyGame.WHITE) {
                    myServerSend = "" + chosenPieceIndex + "," + moveLocationIndex;
                    synchronized (myServerSend) {

                        myServerSend.notify(); // this seems like fail to wake up myServer

                    }
                    System.out.println(myServerSend);
}
如果我将myServerSend声明为公共静态字符串类型,会有问题吗?
有人能帮忙吗?提前谢谢

也许你在等待之前就得到了通知代码。出于这个原因,您应该始终将thread.wait()放在while循环中(也由于虚假的唤醒-但出于这个原因,do while就足够了)。

虽然我不确定您编写的代码到底出了什么问题,但代码本身是不安全的。如果没有其他原因,则无法保证对
wait()
的调用发生在
notify()
之前——如果先发生notify,等待将永远持续。此外,即使您修复了该问题,您仍然没有正确的代码:

线程也可以在不被通知、中断或删除的情况下唤醒 超时,所谓的虚假唤醒。但这种情况很少发生 在实践中,应用程序必须通过测试 导致线程被唤醒的情况,以及 如果条件不满足,则继续等待。换句话说,, 等待应始终在循环中发生,如下所示:

 synchronized (obj) {
     while (<condition does not hold>)
         obj.wait(timeout);
     ... // Perform action appropriate to condition
 }
synchronized(obj){
而()
对象等待(超时);
…//执行适合条件的操作
}

<>你可以考虑用A、A或甚至A来替换这个代码。这些类都更容易使用,也不容易出错<代码>等待/
通知
级别较低,更难正确使用。

在没有看到所有代码的情况下给出明确答案有点困难,但问题可能在于:

myServerSend = "" + chosenPieceIndex + "," + moveLocationIndex;
synchronized (myServerSend) {
    myServerSend.notify(); // this seems like fail to wake up myServer
}
您确定此对象(myServerSend)确实与MyServer.myServerSend对象相同吗?看起来myServerSend是在Action类中创建的,根据您所描述的,预期的顺序是MyServer,然后是Action,但正如我所说,myServerSend似乎是在MyServer中创建的

换句话说,如果evens的顺序应该是MyServer,然后是Action,那么我希望锁定对象可以在两者之外创建,或者在MyServer类中创建

所以我猜你不是在同一个物体上同步,如果这是真的,它可以解释你看到的行为


但是,如果您确定这是同一个对象,那么事件的顺序必须是Action,然后是MyServer(或者您会在MyServer中得到一个NullPointerException),如果是这种情况,我猜您是在等待之前通知的,因此您的代码永远停留在等待点,正在等待已丢失的通知。

这两个类中的对象是同一个对象吗?客户端是否可能在服务器实际到达
wait()
之前执行
notify()
?声明的
myServerSend
变量在哪里?我确信myServerSend在两个类中都是相同的对象。在这种情况下,将在服务器端调用Action类。我忘了在这里显示myServerSend的声明,但我非常确定我这样做了,当您为myServerSend引用的对象指定一个新值时,它会被替换(因为字符串是不可变的),这两段代码不可能使用同一个对象。嗨,Sean,谢谢!我明白问题所在。我是否应该将myServer中的wait()函数更改为“synchronized(Action.myServerSend){Action.myServerSend.notify();}”?myServerSend是一个公共静态字符串,在Action classYes中声明,前提是它与您锁定/等待/通知的对象相同。另一种选择可能是(但这可能会使您感到复杂)MyServer在自身上等待(使用“this”关键字)并在MyServer实例上锁定操作。一旦您的第一次迭代开始工作,这可能是以后的改进。然而,请注意,一旦您对此工作感到满意,您可能需要研究java.util.concurrent中的替代机制(自java 5以来)-它们比这里使用的低级机制更容易使用。
myServerSend = "" + chosenPieceIndex + "," + moveLocationIndex;
synchronized (myServerSend) {
    myServerSend.notify(); // this seems like fail to wake up myServer
}