【问题标题】:Setting a field of an object after a call to Object.wait()在调用 Object.wait() 后设置对象的字段
【发布时间】:2017-09-27 10:56:51
【问题描述】:

我有一个可运行的游戏对象。游戏是通过 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 String input 是 Player 类的实例变量。我有一个 Twitter 侦听器在等待某人发布该机器人的推文,然后在收到所述推文后,它将推文文本作为输入并设置此实例变量,从而跳出循环。我对这种方法并不特别满意,因为在这里等待是没有意义的——而且这里不需要使用 notify()——似乎我正在接近这个错误。但是,我不知道如何等待(),然后还访问实例变量输入以更新它,因为线程在同步块中并且无法执行输入的 setter 方法。

有人对更好的方法有任何想法吗?

【问题讨论】:

  • 看看java.util.concurrent.locks.Condition
  • 你的方法对我来说似乎很合理。但是请注意,您不应该通过 == 运算符比较 Java 中的字符串,因为它将比较对象的引用并返回 false 如果它不是同一个对象。请改用.equals() 方法。

标签: java multithreading oop object twitter


【解决方案1】:

调用wait() 时,您需要一个synchronized 块,但它会在等待时立即释放锁。唤醒后会自动重新获得锁。所以你的代码应该是这样的..不需要使用任何超时..

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();
    }
}

【讨论】:

  • 啊,我不知道线程在等待时会释放锁。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2011-09-28
  • 2023-03-03
  • 2010-10-20
  • 1970-01-01
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
  • 2015-10-12
相关资源
最近更新 更多