Answer by Scott Danzig:
When sharing data in a multithreaded program, a thread needs to be able to rely on data being in an expected state in order to interact with it. Let's take a story-writing program, written especially for Quora Top Writerto entertain fellow Quora Top Writer :
Graeme wants to write some spy fiction for Elynn, and believe me, she's eager to read it. So Graeme starts thinking up a short story he knows she'll enjoy. But Elynn keeps grabbing at the uninitialized, empty notebook. Graeme doesn't want Elynn to grab the notebook with a half-finished story. It needs a bad-ass ending!
He decides he has to protect this resource, the notebook, by locking it in a big room that only he has the key for. After Graeme has finished thinking up the story, he opens the door and enters his special room, locking it behind him. Then he writes his story, with Elynn pounding on the door. Graeme yawns, takes a little nap, and then finishes his story, deciding it's a bit hard to sleep with all the commotion outside. So he finally exits, as Elynn grabs the key from him, pushes his butt out the door, and locks it, enjoying her newly initialized spy story. Elynn knows it'll have an ending, because it's completely initialized, and not partially initialized.
This maps somewhat well into real-world software, where if you read a database record, like a customer name, you want to make sure you get the whole name. Otherwise you might think Graeme's last name was Shim and not Shimmin, which would be horrible to sort out during your next audit.
With Java in particular, initialization usually refers to an object's constructor. As's referenced link states, when one thread is running an object's constructor method, other threads are allowed to access it, so you need to ensure they don't, which I hinted at with the locking scheme metaphor. You actually need to protect it not just at initialization, but every time it changes (or mutates). Therefore, it's in your best interest to only protect the data during initialization (using the final keyword, and the builder design pattern if necessary), and never change the data again after that (immutable data!). Then, if you need to change the data, make a copy of it and send that, so any thread using an old copy of your data doesn't need to worry about anything mucking with it.