Multithreading enables you to take advantage of multiprocessors, including multicore and multithreaded processors, primarily through parallelism and scalability. Programmers should be aware of the differences between the memory models of a multiprocessor and a uniprocessor.
Memory consistency is directly interrelated to the processor that interrogates memory. For uniprocessors, memory is obviously consistent because only one processor is viewing memory.
To improve multiprocessor performance, memory consistency is relaxed. You cannot always assume that changes made to memory by one processor are immediately reflected in the other processors' views of that memory.
You can avoid this complexity by using synchronization variables when you use shared or global variables.
Memory barrier synchronization is sometimes an efficient way to control parallelism on multiprocessors.
Another multiprocessor issue is efficient synchronization when threads must wait until all threads have reached a common point in their execution.