These are primitive but powerful mechanisms, which can be used to build more complex mechanisms. A race condition often occurs when two or more threads need to perform operations on the same memory area, but the results of computations depends on the order in which these operations are performed. Both threads are independent entities and have no synchronization between them. Then thread B executes and puts X, which is 1, into the thread B register. Then thread B increments its register to 2.
Nothing is moved to memory X, so memory X stays the same.
A and thread B will execute the three instructions one after the other, and the result would be 3, as expected. Race conditions are usually difficult to discover, because they occur intermittently. For example, if thread A takes a lock and updates the counter, it leaves memory X with a value of 2. A releases the lock, thread B takes the lock and updates the counter, taking 2 as its initial value for X and incrementing it to 3, the expected result. See Using Mutexes for more information about mutexes.