原子性
操作对于其他线程是不可分割的(参见数据库的事务)
updateHostInfo(ip,port){
setIP(ip)
setPort(port)
}
上述操作就是非原子性操作
实现原子性的两种方法:
1.使用锁(lock),软件锁;
2.利用处理器提供的CAS(Compare-And-Swap)指令,硬件锁;
Java对于基本类型变量,long/double的写操作不保证原子性。使用volatile关键字保证原子性
可见性
一个线程对共享变量的修改应该让其他后续会使用该变量的线程得到更新的结果。 对于不同处理器的更新,可能仅仅被写入了高速缓存而不是内存,这对于其他处理器是不可见的,需要进行缓存同步。使用volatile关键字保证。
JLS Java语言规范保证,
父线程在启动子线程之前对共享变量的更新对于子线程是可见的;
一个线程终止后该线程对共享变量的更新对于调用该线程join方法的线程是可见的;
有序性
重排序
编译器和处理器对源代码在单线程运行环境下的优化。
指令重排序:源代码与程序顺序不一致(编译器 javac)、程序顺序与执行顺序不一致(JIT,处理器)。
存储子系统重排序:处理器感知顺序与上述三种顺序不一致(高速缓存,写缓冲器)。
上下文切换和资源征用。