One of the things that professors always tell students is that "the computer only does what you tell it to do". You write your code, compile it, and then it runs exactly as you wrote it.
However, this isn't true. As soon as your run your compiler, the code is out of your hands. It turns out that the compiler, the virtual machine (where applicable), the operating system and the computer itself all conspire to execute something other than what you wrote. The system tries to make it look as if it is running the same code, but it plays a whole lot of tricks to make it run faster. It turns out that this is a large part of the reason that computers have become much, much faster over the last fifty years - they change your code to run as quickly as possible.
Of course, this also means that the system is changing your code without your knowledge. This can cause trouble, especially if you and the system have different assumptions about what it is allowed to do. This can happen a surprising amount, especially in parallel and multithreaded code. As a result, it is important to have a contract between the system and the user - one which defines what the system is and is not allowed to do.
In the Java programming language, this contract is called the Java Memory Model. In this talk, we shall cover three topics: why the system changes your code, how the system changes your code and what you need to understand in order to get your code to behave.