As we will see throughout the rest of this chapter, the combination of these two
properties—visibility across threads and object mutability—gives rise to a great
many complexities when trying to reason about concurrent Java programs.
If we're to write correct multithreaded code, then we want our programs to satisfy a
certain important property. What we want is this:
A safe multithreaded program is one in which it is impossi‐
ble for any object to be seen in an illegal or inconsistent
state by any another object, no matter what methods are
called, and no matter how the application threads are
scheduled by the operating system.
In Chapter 5 , we defined a safe object-oriented program to be one where objects are
moved from legal state to legal state by calling their accessible methods. This defini‐
tion works well for single-threaded code. However, there is a particular difficulty
that comes about when trying to extend it to concurrent programs.
For most mainstream cases, the operating system will schedule threads to run on
particular processor cores at various times, depending on load and what else is run‐
ning in the system. If load is high, then there may be other processes that also need
The operating system will forcibly remove a Java thread from a CPU core if it needs
to. The thread is suspended immediately, no matter what it's doing—including
being partway through a method. However, as we discussed in Chapter 5 , a method
can temporarily put an object into an illegal state while it is working on it, providing
it corrects it before the method exits.
This means that if a thread is swapped off before it has completed a long-running
method, it may leave an object in an inconsistent state, even if the program follows
the safety rules . Another way of saying this is that even data types that have been
correctly modeled for the single-threaded case still need to protect against the
effects of concurrency. Code that adds on this additional layer of protection is called
concurrently safe .
In the next section, we'll discuss the primary means of achieving this safety, and at
the end of the chapter, we'll meet some other mechanisms that can also be useful
under some circumstances.
Exclusion and Protecting State
Any code that modifies or reads state that can become inconsistent must be pro‐
tected. To achieve this, the Java platform provides only one mechanism: exclusion .