【问题标题】:How do you pause a thread until a condition becomes true without busy waiting?如何在不忙于等待的情况下暂停线程直到条件变为真?
【发布时间】:2017-07-09 20:09:08
【问题描述】:

如何在不忙于等待的情况下暂停线程直到条件变为真? 例如,假设我正在检查是否

playerOne.isWalking()

将成为真的,我想在它成为真的时运行一些代码。再次假设 playerOne 是 Player 类的一个实例,它具有函数 isWalking()。我无权访问使 isWalking() 成为真的原因。所以每次我想检查 isWalking() 是否为真时,我都必须从 player 的实例中显式调用该方法。

我已经尝试在同步块中使用等待/通知,但这永远不会起作用,因为我必须手动通知线程在 isWalking() 变为真时唤醒,我不知道它何时变为真.

我尝试使用观察者模式使 Player 成为 observable 的子类,这样我就可以在 isWalking() 变为 true 时调用 update 方法,但我不知道什么时候会发生。

我什至尝试过使用属性,但这也行不通。

这甚至可以在不忙于等待的情况下进行检查吗?不断的轮询和调用那个函数,看是否为真,如果为真,执行代码。

这是我提出的涉及忙等待的糟糕解决方案:

Busy-Waiting solution

【问题讨论】:

标签: java multithreading synchronization listeners busy-waiting


【解决方案1】:

潜在的问题是您使用 getter 方法来获取信息并对其采取行动。这里违反的原则是告诉,不要问!

解决这个问题的 OO 方法是引入一个接口(例如:PlayerMovingListener)。

播放器类将包含实现该接口的对象的实例(或它们的列表)。一旦玩家开始行走,它就会调用由玩家持有的(或所有)侦听器对象实现的接口中定义的isMoving() 方法。
很可能是由你当前的Payer 实现。

【讨论】:

  • 感谢您的快速响应。如果我正在使用的 API 在 Player 的当前实现中有一个 setter,我将无法访问任何 setter。 public boolean isInCombat() { /* compiled code */ } isInCombat() 是我所说的 isWalking() 函数,只是为了清楚起见而重命名。那么还有什么选择吗?
  • “如果我正在使用的 API 在 Player 的当前实现中有一个 setter,我无权访问任何 setter。” - 您无法实现侦听器图案仅在一侧。 Player 类必须提供基础设施来处理监听器。恕我直言,您的程序被设计破坏了
  • 它被设计破坏了。这就是答案!
猜你喜欢
  • 2021-08-09
  • 2013-09-29
  • 2014-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 2012-06-14
相关资源
最近更新 更多