Writing working multi-threaded code is not easy - it's even hard, as as a Delphi expert just wrote in his blog.
In fact, the first step into multi-thread application development could be:
"protect your shared variables with locks (aka critical sections), because you are not sure that the data you read/write is the same for all threads".
The CPU per-core cache is just one of the possible issues, which will lead into reading wrong values. Another issue which may lead into race condition is two threads writing to a resource at the same time: it's impossible to know which value will be stored afterward.