Need help with synchronization
Hi there,
I've been using Java for a long time, but I've never had to use any kind of synchronization before.
I have a program which uses a projector and a camera.
The projector intermittently projects an image onto a wall (in a thread) - It projects nothing, sleeps for another 500ms (with nothing projected), projects something, sleeps for 500ms (while still projecting), in a loop:
Code:
@Override
public void run() {
while(continue){
m_panel.m_project_stuff = false;
m_panel.repaint();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//NEED TO TAKE PICTURE HERE
m_panel.m_project_stuff = true;
m_panel.repaint();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
The camera intermittently takes pictures of the wall.
I need to have it so that the camera only takes a picture when there is nothing projected on the wall. (The program is to do with image processing, when the projection is visible in the camera image it messes up)
It seems the problem is that I can't tell whether or not the projector has projected something (or stopped projecting something). Even if the paint function has completed, it still takes time for the hardware to do its thing right?
So my question is, will synchronisation be able to solve this? And if so, please teach me!!
Thanks!
Re: Need help with synchronization
Have you read the tutorial? It's a good place to start. Lesson: Concurrency (The Java™ Tutorials > Essential Classes)
You're already running into a potential concurrency problem with this little bit of code you posted. Calling repaint() will trigger a call to paintComponent() in the Swing event dispatch thread. There is no guarantee that the EDT will get some CPU time before this thread changes the value again. It's also possible that the EDT won't even be able to see the changes happening in the other thread.
I would do something like this instead: have your projector thread simply sleep for 500ms and call repaint() in a loop. Override paintComponent() and let the EDT manage the value of m_project_stuff. At the end of the paintComponent() method, if the projector is off, call your method that takes the picture. (If it's a fast method, that is. You don't want to tie up the EDT for a long time.) Depending on when everything is loaded, the camera method may also need to be synchronized. Read the part of the tutorial about "happens before" relationships.