JAVA-BASED REAL-TIME PROGRAMMING
JAVA-BASED REAL-TIME PROGRAMMING
JAVA-BASED REAL-TIME PROGRAMMING
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
3. Multi-Threaded Programming<br />
• Since C1 is continuing after wait, according to the shown implementation<br />
assuming that the buffer is not empty, C1 tries to get<br />
the next object. There are no such object, and the buffer (and the<br />
application) fails 4 .<br />
2. It can be difficult to keep track of what condition other threads are blocked<br />
on, or it can be hard to verify correctness or revise the code. In the referred<br />
buffer example it may appear to be simple, but does the buffer<br />
work correctly even for maxSize equal to one?<br />
If we would add another method awaitEmpty that should block until the<br />
buffer is empty (useful during application shutdown), or an additional<br />
method awaitFull that should block until the buffer is full (useful for<br />
special handling of overflows), when and how many times should notify<br />
then be called?<br />
It is so easy to overlook some cases, and actually taking care of all cases<br />
by the appropriate logic (such as counters for threads blocked on this<br />
or that condition) leads to unnecessary complex code that is hard to<br />
understand and maintain.<br />
Remedy: Use notifyAll instead of notify, and let other threads reevaluate<br />
their conditions (assuming the remedy for item 1 is used). The<br />
exception from this rule is when optimizing for well known and performance<br />
critical parts of the application.<br />
3. How do we ensure concurrency correctness and predictability on any<br />
(Java-compatible) platform? As an example, assume we have two consumer<br />
threads (C1 and C2) and five producer threads (P1 to P5), and<br />
assume these use our buffer according to the following:<br />
• The buffer (Buffer in Figure 3-8) is given a capacity of four (maxSize==4).<br />
• Both C1 and C2 call fetch, and hence they get blocked since the<br />
buffer is empty.<br />
• P1 puts an object in the buffer by calling post, which calls notify.<br />
One of C1 and C2, say C1, is moved to the monitor queue while<br />
the other consumer remains in the condition queue.<br />
• Before C1 gets scheduled for execution, the other producers (P2 to<br />
P5) try to post an object. Since the buffer was not empty, C2 was<br />
not notified. This is either a bug or C1 has to notify C2 somehow.<br />
However, the last producer, say P5, then also gets scheduled before<br />
C2 and post blocks since the buffer now is full.<br />
4 Programming in Java, application failure typically means an ArrayOutOfBoundException<br />
or a NullPointerException that can be caught and handled, or at least we know what<br />
and where it went wrong. Using an unsafe language such as C++, the system can crash (at<br />
a later stage) without messages.<br />
78 2012-08-29 16:05