Is writing an object to an ObjectOutputStream a thread-safe operation?

Absolutely not!
Serialization, i.e. passing an object reference to the writeObject() method
of ObjectOutputStream,
is not an atomic operation. Serialization involves traversing a
graph of objects, each of which contributes to the state of the object
being serialized, saving the
state of each object in turn. This is a time-consuming procedure;
if other threads are allowed to concurrently access or modify any one
of the objects in the graph you could get underfined and unwanted results.

The solution is to protect the objects in the graph from modification
during the serialization, or to design your objects such that the graph
is consistent even if individual objects are modified during serialization.
This is, in general, a non-trivial task. Proper use of the transient keyword and
customization of serialization through the use of readObject() and writeObject()
will allow you to control exactly what parts of your graph are serialized.