0

How do you pause a thread until a condition becomes true without busy waiting? For example, suppose I'm checking to see whether

playerOne.isWalking()

Is going to be true and I want to run some code when it does become true. Again suppose playerOne is an instance of the class Player which then has the function isWalking(). I do not have access to the what makes isWalking() become true. So everytime I want to check to see if isWalking() is true, I have to call the method from an instance of player explicitly.

I've tried using Wait/Notify in synchronized blocks but that wouldn't ever work because I would have to manually notify the Thread to wake up when isWalking() becomes true and I don't know when it will become true.

I've tried using the observer pattern to make Player a subclass of observable so that I can call the update method when isWalking() becomes true but again I don't know when that will happen.

I've even tried using Propertys but that wouldn't work either.

Is this even possible to check without busy-waiting? Constantly polling and calling that function to see if it is true, then if it is true, execute the code.

This was a bad solution I made involving busy-waiting:

Busy-Waiting solution

TheAppFoundry
  • 93
  • 1
  • 9
  • Welcome to Stack Overflow! Please take the [tour](http://stackoverflow.com/tour), have a look around, and read through the [help center](http://stackoverflow.com/help), in particular [How do I ask a good question?](http://stackoverflow.com/help/how-to-ask) and [What topics can I ask about here?](http://stackoverflow.com/help/on-topic). – Timothy Truckle Jul 09 '17 at 20:10

1 Answers1

0

The underlaying problem is that you use a getter method to aquire an information and act on it. The principle which is violated here is Tell, don't ask!.

The OO whay to solve this is to introduce an interface (e.g.: PlayerMovingListener).

The player class would hold an instance of an object implementing that interface (or a list of them). As soon as the player starts walking it calls the isMoving() method defined in the interface implemented by the (or all) listener object(s) held by the player.
Most likely is triggered by a setter method in your current Payer implementation.

Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51
  • I appreciate the quick response.I don't have access to any setter if there was one in the current implementation of Player from the API I'm using. `public boolean isInCombat() { /* compiled code */ }` isInCombat() is the isWalking() function I was talking about, just renamed for sake of clarity. So is there any options left? – TheAppFoundry Jul 09 '17 at 20:33
  • *"I don't have access to any setter if there was one in the current implementation of Player from the API I'm using."* - You cannot implement the listener pattern on one side only. The `Player` class must provide the infrastructure to handle the listeners. IMHO your program is *broken by design*. – Timothy Truckle Jul 09 '17 at 20:50
  • It's broken by design. That answers it! – TheAppFoundry Jul 09 '17 at 20:51