我有一个可运行的游戏对象。游戏是通过 Twitter 进行的,因此当游戏需要玩家输入时,我有一个如下所示的函数:
private synchronized void waitForInput() {
input = "";
while(input == ""){
System.out.println("Waiting...");
try{
synchronized(this){
// wait for a second then continue to check the loop condition
this.wait(1000);
}
}
catch(Exception e){
System.out.println("failed to wait.");
e.printStackTrace();
}
}
System.out.println("Finished waiting.");
}
私有(private) volatile 字符串输入
是Player类的实例变量。我有一个 Twitter 监听器,等待有人向机器人发送推文,然后在收到所述推文后,它将推文文本作为输入并设置此实例变量,从而跳出循环。我对这种方法不是特别满意,因为等待在这里是毫无意义的 - 并且这里不需要使用 notification() - 看来我正在接近这个错误。但是,我不知道如何 wait() 然后访问实例变量输入来更新它,因为线程位于同步块(synchronized block)中并且无法执行输入的 setter 方法。
有人有更好的方法的想法吗?
最佳答案
当调用wait()
时,你需要一个synchronized
block ,但它会在等待时立即释放锁。当它醒来时,它会自动重新获得锁定。所以你的代码应该是这样的..不需要使用任何超时..
private void waitForInput() {
String input = "";
// Though we are not waiting infinitely without timeout, we still need
// while loop.
// Since JVM in some cases might wake-up thread without notify calls,
// this is called "spurious" wake-ups.
synchronized (this) {
while (input.equals("")) {
System.out.println("Waiting...");
try {
this.wait();//Wait infinitely, or till notify called.
//Lock is released but current thread is blocked, so call on some Async thread if required.
} catch (Exception e) {
System.out.println("failed to wait.");
e.printStackTrace();
}
}
}
System.out.println("Finished waiting.");
}
//Your twitter bot should call this method, when new input received.
public void wakeup(String input) {
synchronized (this) {
this.input = input;
notifyAll();
}
}
关于java - 调用 Object.wait() 后设置对象的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43695177/