竞态:计算结果的正确性与时间有关的现象就称为竞态
解释竞态的结果:二维表分析法
竞态模式:read-modify-write、check-then-act(检测而后运行)
线程安全性:一个类在单线程环境下能够运行正常,并且在多线程环境下、使用时不必为其做任何改变的情况下也能运作正常,则其称为是线程安全的
线程安全问题概括起来三个方面:原子性、可见性、有序性
原子性:对共享变量的访问操作,若该操作从其执行线程以外的任意线程来看是不可分割的,那么该操作就称为原子操作。(原子操作+原子操作 != 原子操作)
可见性:一个线程对某个共享变量更新后,后续访问该变量的线程可能无法立刻读取到这个更新结果,甚至永远也无法读取到该更新结果;(能读取到更新后的结果则为可见、否则为不可见)可见性常与存储系统有关,线程对变量的更新过程:变量存储在所用线程的寄存器上--写缓冲器—高速缓存—主内存;通知其他处理器时,其他处理器可能仅仅将更新通知的内容存入无效化队列中;所以多线程对共享变量的操作是,将共享变量从主内存移动到各自的寄存器中,修改值后通过写缓冲器、高速缓存、再回到主内存中;除主内存外的其他部件统称处理器缓存
有序性:一个处理器上运行的一个线程所执行的内存访问操作在另一个处理器上运行的其他线程看来是乱序的;乱序:内存访问操作的顺序看起来像是发生了变化,其中涉及到重排序概念:指令重排序(来源编译器、处理器)、存储子系统重排序(来源高速缓存、写缓冲器)
保障内存访问的顺序性:逻辑上的部分禁止重排序,通过调用处理器提供的相应指令—内存屏障来实现的、关于内存屏障在第三章会有更详细的讲解
上下文切换:多线程共享同一个处理器的产物
线程的活性故障:死锁(鹬蚌相争)锁死(王子救公主、王子已死)活锁(猫咬尾巴)饥饿