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.
class Producer extends Thread {<br />
public void run() {<br />
prod = source.get();<br />
buffer.post(prod);<br />
}<br />
}<br />
class Consumer extends Thread {<br />
public void run() {<br />
cons = buffer.fetch();<br />
sink.put(cons);<br />
}<br />
}<br />
3.3. Objects providing mutual exclusion – Monitors<br />
class Buffer {<br />
synchronized void post(Object obj) {<br />
if (buff.size()== maxSize) wait();<br />
if (buff.isEmpty()) notify();<br />
buff.add(obj);<br />
}<br />
synchronized Object fetch() {<br />
if (buff.isEmpty()) wait();<br />
if (buff.size()== maxSize) notify();<br />
return buff.remove();<br />
}<br />
}<br />
// This Buffer is badly implemented!<br />
Figure 3.8: Classes, with attributes and initialization left out for brevity,<br />
implementing producer-consumer communication via a bounded buffer based<br />
on java.util.ArrayList. The if (...) wait(); makes the buffer fragile: additional<br />
calls of notify (e.g., in other methods) or additional threads could course the<br />
buffering to fail.<br />
is not full. Assuming the simplest case with only one producer and one consumer,<br />
an straightforward but fragile implementation could be according to<br />
Figure 3-8. In a more general setting, with more threads involved or the buffer<br />
functionality being extended, the following problems arise (see Figure 3-7):<br />
1. Even if the notifying thread calls notify only when the condition to<br />
proceed is OK for the waiting thread, the condition may again not be true<br />
when the waiting thread is continuing! Assume we have one producer P<br />
and two consumers C1 and C2, using the Buffer like:<br />
• C1 tries to fetch an object, but gets blocked on since the buffer is<br />
empty.<br />
• P posts an object to the buffer, and since the buffer was empty<br />
that results in a notification of C1 that is moved from the condition<br />
queue to the monitor queue.<br />
• Before C1 is scheduled for execution, that is, before C1 actually<br />
enters the exclusive area, C2 (having a higher priority) continues<br />
(for example after a sleep that was completed after a clock interrupt)<br />
and tries to enter the monitor. If this happens before P has<br />
left the exclusive area, both C1 and C2 are blocked in the monitor<br />
queue. (C1 about to continue after wait, but C2 first in the queue<br />
due to higher priority.)<br />
• When P leaves the monitor, there are one object in the buffer. C2<br />
enters the exclusive area, gets the object, and when leaving C1 is<br />
moved to the ready queue of the scheduler and is allowed to enter<br />
the monitor (owning the lock).<br />
77