Groovy wait/notify

27,322

Solution 1

As Brian says, multithreading and concurrency is a huge area, and it is easier to get it wrong, than it is to get it right...

To get your code working, you'd need to have something like this:

abstract class Actor implements Runnable {
  synchronized void proceed() { notify() }
  synchronized void pause()   { wait()   }
}

class MyActor extends Actor {
  void run() {
    println "hi"
    pause()
    println "hi again"
  }
}


def theactor = new MyActor()             // Create an instance of MyActor
def actorThread = new Thread( theactor ) // Create a Thread to run this instance in
actorThread.start()                      // Thread.start() will call MyActor.run()
Thread.sleep( 500 )                      // Make the main thread go to sleep for some time so we know the actor class is waiting
theactor.proceed()                       // Then call proceed on the actor
actorThread.join()                       // Wait for the thread containing theactor to terminate

However, if you are using Groovy, I would seriously consider using a framework like Gpars which brings concurrency to Groovy and is written by people who really know their stuff. I can't think of anything that llows this sort of arbitrary pausing of code however... Maybe you could design your code to fit one of their usage patterns instead?

Solution 2

Threading is a big topic and there are libraries in Java to do many common things without working with the Thread API directly. One simple example for 'Fire and Forget' is Timer.

But to answer your immediate question; another thread needs to notify your thread to continue. See the docs on wait()

Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).

One simple 'fix' is to just add a fixed duration to your wait call just to continue with your exploration. I would suggest the book 'Java Concurrency in Practice'.

synchronized void pause() {
        //wait 5 seconds before resuming.
        wait(5000)
    }
Share:
27,322
Ian Macalinao
Author by

Ian Macalinao

I love writing code and helping others write better code.

Updated on January 31, 2020

Comments

  • Ian Macalinao
    Ian Macalinao about 4 years

    I have the following Groovy code:

    abstract class Actor extends Script {
        synchronized void proceed() {
            this.notify()
        }
    
        synchronized void pause() {
            wait()
        }
    }
    
    class MyActor extends Actor {
        def run() {
            println "hi"
            pause()
            println "hi again"
        }
    }
    
    def theactor = new MyActor()
    theactor.run()
    theactor.proceed()
    

    When I run the code, I want the code to output "hi" and "hi again". Instead, it just stops at "hi" and gets stuck on the pause() function. Any idea on how I could continue the program?

  • Ian Macalinao
    Ian Macalinao almost 13 years
    What I'm doing is making scripted NPCs for a game. I will trigger the proceed function when the player interacts with the NPC. Thanks for the link to Gpars; I'll look into it.
  • tim_yates
    tim_yates almost 13 years
    I'd have a look at this chapter here on Actors. Not sure how well actors scale to the potentially tousands+ you might need for a game? Might be worth asking on the mailing list?
  • Ian Macalinao
    Ian Macalinao almost 13 years
    Thanks for the links. I tried out your code and it didn't work correctly, though. I just resorted to checking a boolean every server tick. I looked at Gpars and decided I didn't really need it. Thanks for the help, though.