Page 834 - Introduction to Programming with Java: A Problem Solving Approach
P. 834
800 Appendix 9 Multithreading
The beTogether method prints the name of the thread that called it and the cycle number’s current value. In a more complete model, the beTogether method would also call Predator and Prey methods to change the masses of these objects for the time they were apart. Then it would calculate the change in weights in the violent together period.
If you run the program in Figures A9.1, A9.2, A9.3, and A9.4, this is what you’ll get: Output:
prey start beApart
prey start beApart
prey start beApart
prey start beApart
prey run finished.
0
1
2
3
predator finish beTogether 3
predator finish beTogether 3
predator finish beTogether 3
predator finish beTogether 3
predator run finished.
Is this what you want? No! Because the prey and predator threads run in parallel but only the predator thread contains delays, they do not interleave properly. The prey thread finishes quickly, whereas even the first output of the predator thread does not occur until much later.
Synchronization
Apago PDF Enhancer
When different threads access a common object, they should be synchronized. We synchronize them rela- tive to the common object by including the synchronized modifier in the heading of any common-object method that might be called by a thread that must be synchronized. In addition, we use a semaphore to give access to only one thread at a time—and block (temporarily stop) all other threads.
Figure A9.5a contains a corrected version of the first part of the Encounter class of Figure A9.4. In this part of the corrected class definition, the only thing different is the addition of another instance vari- able, a boolean semaphore that indicates which thread currently has access to the common object. This additional declaration appears in bold-face type.
Figure A9.5b contains a corrected version of the second part of the Encounter class of Figure A9.4. All the new code appears in bold-face type. This shows what you do to synchronize multiple threads. First, include the synchronized modifier in the heading of those methods you want to synchronize. Then, at the start of each of those methods, put a while loop with a try block that contains the simple statement:
wait();
This statement blocks access to the rest of that method, so you should make the while condition true when you want to block access. Finally, insert a pair of special statements right before the return. The first of these special statements should set the phase of the semaphore to make the preceding while condition true. The second of these statements should be:
notifyAll();
In both cases the while loop’s condition is the phase of the semaphore that blocks the calling thread. If this condition is true when an external thread calls the method, flow goes immediately to the wait