原子性、可见性和有序性
1. 原子性 操作是原子的,则它不可被分割。从另一个线程的视角来看,它不应该看到这个操作的中间状态,只能看到两种状态:①还没开始执行 ② 已经执行结束。 在多个线程访问临界资源时,如果临界区的代码不是原子的,则一个线程执行到某个中间状态,然后被时钟中断,另一个线程接着执行,就会覆盖数据或访问到不正确的数据。 2. 可见性 由于在存储器层次结构中,更高层的数据是更低层数据的一个子集,该数据副本可能存在存储系统的不同层中。为了提高性能,高层数据写回底层并不是实时的,因此可能造成在某时刻高层数据和底层数据的不一致。 在多核cpu下,由于每个核内部都内置了cache,各个核的cache可能缓存了同一个内存地址的数据,cache之间如果没有某种机制协调,会导致数据不一致(各个线程看到相同数据的值不一样)。 当一个线程修改了共享数据后,我们希望其他线程也能看到这个改变后的结果。如果其他线程看不到这个修改后的数据,继续访问缓存的旧数据,就可能出现问题。 3. 有序性 ① 哪些地方可能产生重排序? 源代码-->字节码/机器码-->存储系统-->CPU 会造成重排序的有:① 编译器 ② 存储系统 ③ CPU的执行单元。 ② 为什么要重排序呢? 为了提高性能。比如更利于cpu的流水、乱序执行;cpu的异步写入store buffer;store buffer的合并写操作等。 ③ 重排序会造成什么影响呢