Java The Complete Reference, Seventh Edition

(Greg DeLong) #1
// Now, allow a context switch -- if possible.
Thread.sleep(10);
}
} catch (InterruptedException exc) {
System.out.println(exc);
}

// Release the permit.
System.out.println(name + " releases the permit.");
sem.release();
}
}

The output from the program is shown here. (The precise order in which the threads
execute may vary.)

Starting A
A is waiting for a permit.
A gets a permit.
A: 1
Starting B
B is waiting for a permit.
A: 2
A: 3
A: 4
A: 5
A releases the permit.
B gets a permit.
B: 4
B: 3
B: 2
B: 1
B: 0
B releases the permit.

The program uses a semaphore to control access to thecountvariable, which is a static
variable within theSharedclass.Shared.countis incremented five times by therun( )
method ofIncThreadand decremented five times byDecThread. To prevent these two
threads from accessingShared.countat the same time, access is allowed only after a permit
is acquired from the controlling semaphore. After access is complete, the permit is released.
In this way, only one thread at a time will accessShared.count, as the output shows.
In bothIncThreadandDecThread, notice the call tosleep( )withinrun( ). It is used to
“prove” that accesses toShared.countare synchronized by the semaphore. Inrun( ), the call
tosleep( )causes the invoking thread to pause between each access toShared.count. This
would normally enable the second thread to run. However, because of the semaphore, the
second thread must wait until the first has released the permit, which happens only after all
accesses by the first thread are complete. Thus,Shared.countis first incremented five times
byIncThreadand then decremented five times byDecThread. The increments and decrements
arenotintermixed.

792 Part II: The Java Library

Free download pdf