Reputation: 816
So this is my code that polls for a change in my app's model.
Thread refreshThread = new Thread(new Runnable() {
public void run() {
while(true)
{
if(TasksManager.isDirty())
{
TasksManager.refreshTasks(true);
panel.repaint();
}
}
}
});
refreshThread.start();
Right now it is an immense CPU hog. Here's the breakdown of what happens.
I didn't want the TaskManager to start the refresh since it doesn't hold any reference to the Viewing Panel.
One idea I have is to use a condition.await(). The TaskManager can signal the condition when it has been marked as dirty. But I see that Locks and Conditions go hand in hand. Would it be okay to use a Condition without acquiring a Lock at the beginning of the function?
Upvotes: 1
Views: 3321
Reputation: 21419
You can use wait()
and notifyAll()
to avoid high CPU usage:
private final Object dirtyLock = new Object();
Thread refreshThread = new Thread(new Runnable() {
public void run() {
while(true){
synchronized(dirtyLock){
dirtyLock.wait(); // Send this thread to sleep until dirtyLock is unlocked
}
TasksManager.refreshTasks(true);
panel.repaint();
}
});
refreshThread.start();
// When your TaskManager becomes dirty, do the following
public void changeToDirty(){
TaskManager.setDirty(true);
synchronized(dirtyLock){
dirtyLock.notifyAll();
// this will release the refresh thread which will repaint and then go to sleep
}
}
Upvotes: 5
Reputation: 4258
Why aren't you using listeners for this?
If you have a simple subclass of TasksManager called ContentChangedListener. You can then have the panel.repaint() stuff declared in a listener which is registered with TasksManager from whoever is interested. Many listeners can be registered as required.
In the place of the code which marks TasksManager as dirty, replace it with a loop to notify all listeners of a change.
This solution has the advantage of not requiring another thread or looping.
Upvotes: 4