Java Reference
In-Depth Information
pool-1-thread-2 wrote 12 to element 4.
Next write index: 5
pool-1-thread-2 wrote 13 to element 5.
Next write index: 6
Contents of SimpleArray:
[11, 2, 3, 0, 12, 13]
Fig. 23.7 | Executing two Runnable s to add elements to a shared array. ( Caution: The example
of Figs. 23.5-23.7 is not thread safe.) (Part 3 of 3.)
ExecutorService Method awaitTermination
Recall that ExecutorService method shutdown returns immediately. Thus any code that
appears after the call to ExecutorService method shutdown in line 23 will continue exe-
cuting as long as the main thread is still assigned to a processor . We'd like to output the Sim-
pleArray object to show you the results after the threads complete their tasks. So, we need
the program to wait for the threads to complete before main outputs the SimpleArray ob-
ject's contents. Interface ExecutorService provides the awaitTermination method for
this purpose. This method returns control to its caller either when all tasks executing in
the ExecutorService complete or when the specified timeout elapses. If all tasks are com-
pleted before awaitTermination times out, this method returns true ; otherwise it returns
false . The two arguments to awaitTermination represent a timeout value and a unit of
measure specified with a constant from class TimeUnit (in this case, TimeUnit.MINUTES ).
Method awaitTermination throws an InterruptedException if the calling thread is
interrupted while waiting for other threads to terminate. Because we catch this exception
in the application's main method, there's no need to re-interrupt the main thread as this
program will terminate as soon as main terminates.
In this example, if both tasks complete before awaitTermination times out, line 34
displays the SimpleArray object's contents. Otherwise, lines 37-38 display a message indi-
cating that the tasks did not finish executing before awaitTermination timed out.
Sample Program Output
Figure 23.7's output shows the problems (highlighted in the output) that can be caused by
failure to synchronize access to shared mutable data . The value 1 was written to element 0 , then
overwritten later by the value 11 . Also, when writeIndex was incremented to 3, nothing was
written to that element , as indicated by the 0 in that element of the printed array.
Recall that we added calls to Thread method sleep between operations on the shared
mutable data to emphasize the unpredictability of thread scheduling and increase the likeli-
hood of producing erroneous output. Even if these operations were allowed to proceed at
their normal pace, you could still see errors in the program's output. However, modern
processors can handle the simple operations of the SimpleArray method add so quickly
that you might not see the errors caused by the two threads executing this method concur-
rently, even if you tested the program dozens of times. One of the challenges of multi-
threaded programming is spotting the errors—they may occur so infrequently and unpredictably
that a broken program does not produce incorrect results during testing, creating the illusion that
the program is correct. This is all the more reason to use predefined collections that handle
the synchronization for you.
 
Search WWH ::




Custom Search