Groovy Wait/Notify
I Have the Following Groovy Code: Abstract Class Actor Extends Script { Synchronized Void Proceed() { This. Notify() } Synchronized Void Pause() { Wait() } }...
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?
2 Answers
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?
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)
}