Concepts of Programming Languages

(Sean Pound) #1

624 Chapter 13 Concurrency


influence task scheduling, how and when tasks start and end their executions,
and how and when they are created.
A semaphore is a data structure consisting of an integer and a task descrip-
tion queue. Semaphores can be used to provide both competition and coop-
eration synchronization among concurrent tasks. It is easy to use semaphores
incorrectly, resulting in errors that cannot be detected by the compiler, linker,
or run-time system.
Monitors are data abstractions that provide a natural way of providing
mutually exclusive access to data shared among tasks. They are supported by
several programming languages, among them Ada, Java, and C#. Cooperation
synchronization in languages with monitors must be provided with some form
of semaphores.
The underlying concept of the message-passing model of concurrency is
that tasks send each other messages to synchronize their execution.
Ada provides complex but effective constructs, based on the message-passing
model, for concurrency. Ada’s tasks are heavyweight tasks. Tasks communicate
with each other through the rendezvous mechanism, which is synchronous mes-
sage passing. A rendezvous is the action of a task accepting a message sent by
another task. Ada includes both simple and complicated methods of controlling
the occurrences of rendezvous among tasks.
Ada 95+ includes additional capabilities for the support of concurrency,
primarily protected objects. Ada 95+ supports monitors in two ways, with tasks
and with protected objects.
Java supports lightweight concurrent units in a relatively simple but effec-
tive way. Any class that either inherits from Thread or implements Runnable
can override a method named run and have that method’s code executed con-
currently with other such methods and with the main program. Competition
synchronization is specified by defining methods that access shared data to be
implicitly synchronized. Small sections of code can also be implicitly synchro-
nized. A class whose methods are all synchronized is a monitor. Cooperation
synchronization is implemented with the methods wait, notify, and notify-
All. The Thread class also provides the sleep, yield, join, and interrupt
methods.
Java has direct support for counting semaphores through its Semaphore
class and its acquire and release methods. It also had some classes for
providing nonblocking atomic operations, such as addition, increment, and
decrement operations for integers. Java also provides explicit locks with the
Lock interface and ReentrantLock class and its lock and unlock methods.
In addition to implicit synchronization using synchronized, Java provides
implicit nonblocking synchronization of int, long, and boolean type vari-
ables, as well as references and arrays. In these cases, atomic getters, setters,
add, increment, and decrement operations are provided.
C#’s support for concurrency is based on that of Java but is slightly more
sophisticated. Any method can be run in a thread. Both actor and server threads
are supported. All threads are controlled through associated delegates. Server
threads can be synchronously called with Invoke or asynchronously called
Free download pdf