In the previous chapter, we covered a lot of ground: we examined how to create and start threads, how to arrange for them to terminate, how to name them, how to monitor their lifecycles, and so on. In the examples of that chapter, however, the threads that we examined were more or less independent: they did not need to share data between them.
There were some exceptions to that last point. In some examples, we
needed the ability for one thread to determine whether another was
finished with its task (i.e., the
flag). In others, we needed to change a character variable that was used
in the animation canvas; this was done by a thread different than the
Swing thread that redraws the canvas. We glossed over the details at the
time, which may have given the implication that they are minor issues.
However, we must understand that when two threads share data, complexities
arise. These complexities must be taken into consideration whether we're
implementing a large shared database or simply sharing a
In this chapter, we look at the issue of sharing data between threads. Sharing data between threads can be problematic due to what is known as a race condition between threads that attempt to access the same data more or less simultaneously (i.e., concurrently). In this chapter, we examine the concept of a race condition and mechanisms that solve the race condition. We will see how these mechanisms can be used to coordinate access to data as well ...