JAVA-BASED REAL-TIME PROGRAMMING
JAVA-BASED REAL-TIME PROGRAMMING
JAVA-BASED REAL-TIME PROGRAMMING
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
3.3. Objects providing mutual exclusion – Monitors<br />
• We now have two threads in the condition queue, one consumer<br />
blocked on buffer empty and one producer blocked on buffer full,<br />
and one of them will most likely be stuck there for a long time<br />
(possibly forever if it was the producer and if that thread was to<br />
serve the next application event). This holds even if we would have<br />
implemented the Buffer using while instead instead of if according<br />
to item 1, but the remedy of item 2 works.<br />
Items 2 and 3 are similar in that they both motivate the use of notifyAll<br />
instead of notify. The difference is that while we according to item 2 actually<br />
may be able to optimize and use notify, fully tested to be logically correct on<br />
one JVM/OS, item 3 points at the concurrency problem that implies the risk<br />
of application failure sometimes on some platforms.<br />
Another problem is that at any place within your program, where a reference<br />
to your monitor is available, synchronized(monitor){monitor.notifyAll();}<br />
can be called and interfere with your methods. The same of course applies<br />
to notify and wait. The remedies above help also in this case. For optimized<br />
libraries, however, private notification objects can be used, like the private<br />
lock object described in the above section about Synchronization details.<br />
A radical remedy would be to always notify all threads whenever anything<br />
has changed. For instance, the Buffer class in Figure 3-8 could be implemented<br />
like in the left version in Figure 3-9, where the suggestions from the above<br />
items have been considered. Decreased performance comes from notifyAll<br />
(which is a system call that is more expensive than checking ordinary data)<br />
being called even if there for sure is no thread in the condition queue, and<br />
there are no logic separating between the full and empty cases. A reasonable<br />
trade-off (using notifyAll to avoid the described problems) is shown to the<br />
right in Figure 3-9.<br />
In short, as rules of thumb for programming:<br />
1. Always use while in front of wait: while (!okToProceed) wait();<br />
2. Instead of notify(): use notifyAll();<br />
3. Tune performance when needed, using notify() or condition objects explained<br />
below.<br />
Keep Figure 3-7 in mind when you develop your monitor methods.<br />
Timeout on waiting<br />
There are situations when waiting for a condition to be fulfilled may not take<br />
more than a certain amount of time. After that time we want to get a timeout.<br />
For this purpose, there are two versions of wait accepting timeout arguments:<br />
79