"For it to end up with the right value at the end (M x N), two things need to be true." <-- the two things (immediate visibility and atomicity) are not strictly required. this is only required if all intermediate values are to be observed by the running threads. otherwise you can end up with the correct answer (M x N) without requiring threads to coordinate each write.