06.08.2013 Views

JAVA-BASED REAL-TIME PROGRAMMING

JAVA-BASED REAL-TIME PROGRAMMING

JAVA-BASED REAL-TIME PROGRAMMING

SHOW MORE
SHOW LESS

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 />

withdraw method) but concurrent calls of withdraw can give the wrong<br />

result. This is because the withdraw method no longer is reentrant. For<br />

instance, one caller (with low priority) locks the resource and carries out<br />

the transaction, while a second thread (with high priority) preempts the<br />

first thread between lines 16 and 17. When resuming, the first thread<br />

will return the result of the second call and the result of the first transaction<br />

is lost, that is, if amount>balance.<br />

Making a method or function reentrant by only using local variables (allocated<br />

on the stack of each thread) is standard; we need to understand that no<br />

matter if we use a language supporting synchronized or not. However, with<br />

the availability of synchronized as in Java, we do not need to introduce the<br />

ans variable at all. Furthermore, returning from a method never results in the<br />

resource being left in its locked state; on return the Java compiler produces<br />

the executable code that unlocks the object.<br />

Basic use of keyword synchronized<br />

There are cases when synchronized blocks are appropriate, but in general we<br />

better follow a few simple rules:<br />

1. For each class, decide if an instance should be an ordinary object (not<br />

caring about concurrency), a thread object, or a monitor. Do not mix<br />

threads and monitors.<br />

2. Monitors should have all public methods synchronized (except the constructors)<br />

and no public attributes. Subclasses of monitors should also<br />

have to declare all methods synchronized since synchronized is not inherited.<br />

3. If you need to make an ordinary class thread safe, you could create a<br />

monitor by defining a subclass, but then you have to override all methods<br />

in order to declare them as synchronized. Methods that are final is a<br />

problem. Instead of subclassing, it is usually better to write a wrapper<br />

class being a monitor containing the ordinary object.<br />

4. Do not use synchronized blocks, which are contradictory to proper objectoriented<br />

design of concurrent software and to the monitor concept as<br />

such.<br />

The reason for rule A is that the actions of a thread is defined via a method<br />

(run) which from a purely object-oriented point of view is a method like any<br />

other, with access to all attributes of the object. Mutual exclusion between the<br />

internal thread (executing the run method) and the external threads (calling<br />

the monitor methods) would require the run method to be synchronized as<br />

well. Another alternative could be to only access the attributes of the object<br />

69

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!