I'd like to know how to call different functions cross thread in Java. Right now the way I'm doing it is to write my run() function of my thread as so
public volatile boolean invokeMyFunction = false;
public void run() {
while(true) {
if(invokeMyFunction) {
MyFunction();
invokeMyFunction = false;
}
}
}
and if I want to run the function MyFunction() from outside that thread write "whateverobject.invokeMyFunction = true" and it will run my function from within the thread because that loop will pick it up. This works great for me, but it uses 100% of my CPU because of that while(true) loop. I could fix that by just slapping a Thread.sleep(1000) inside the loop but that seems messy and I can't help but to believe there's a better way of doing this.
I think here, the easiest and CPU-friendly way to achieve this is
public void run() {
while(true) {
synchronized(foo) {
while(!invokeMyFunction) {
foo.wait();
}
}
MyFunction();
invokeMyFunction = false;
}
}
The above code runs in it's own Thread. Another thread can do this to let the first Thread run MyFunction():
invokeMyFunction = true;
foo.notifyAll();
Note that a) You cannot make invokeMyFunction a Boolean and synchronize over it because there are only two Booleans in all of java :) b) If invokeMyFunction is set n times, it might still run fewer times if invokeMyFunction is set to true while it was not false. c) Using a BlockingQueue might be easier and would allow Thread 1 to run arbitrary functions:
while(true) {
Runnable next = queue.take();
next.run()
}
And another thread would tell it to run MyFunction like this:
queue.put(new Runnable() {
void run() {
MyFunction();
}
});
Seems easier to me :) Also, if you then want n Threads to run whatever comes through the queue, you just need to spawn n Threads that listen on the queue. Or you can learn how to use thread pools: http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
Note:
queue.put() blocks until a new space is available in the BlockingQueue, i.e. it blocks if it is "full". See the implementation docs of whatever BlockingQueue implementation you are using to see if your queue has a limit. In any case, make sure you're not adding more items to work with than you can process for too long.
You can put a monitor in your thread, and wait on that monitor. When you invoke the function, tell the monitor to release someone from it (and it should only have that one) who can run your function and then go back to waiting again.
On the flip side, there's nothing inherently wrong with the sleep route either. I see why you would call it messy, but it runs a lower chance of making a silly mistake and provides for looser coupling between your services.
(Side note - you don't need to put a monitor in the thread. You could use that object as the monitor instead of an internal monitor. But then you open yourself up to someone else potentially interfering with it, so it's best to use a private internal Object as your monitor.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With