并发中的可见性
如下图,当线程A读取变量i时,会从内存中读取数据,并缓存一份在CPU1内部的高速缓存中,然后线程A将变量i的值修改为2,但是还没来得及回写到内存,此时线程B也读取变量i,也会从内存中读取,读到的变量i仍然为1,此时就出现了可见性问题。
JAVA中可以通过关键字volatile来保证变量的可见性,对于加了volatile的变量,线程读取该变量值时会直接从内存中读取,在修改变量时会同时修改CPU高速缓存和内存中的值。
并发中的原子性
JAVA并发原子性指的是在多线程并发的情况下,一段代码或者操作要么完全执行成功,要么完全不执行,不出现执行一半被其他线程打断或者干扰的情况。
以i++为例,底层执行对应三条指令:
1.从内存中读取i
2.执行i+1
3.回写i的值到CPU高速缓存
但是有可能线程A执行了第1条指令后,就发生了线程切换,线程A暂停执行,此处如果线程B也是执行i++,并且把3条指令都执行完了,那么线程B得到的结果i=2,然后线程A又切换回来继续执行,最终导致的线程A得到的结果也是i=2,正常来说i应该等于3的,这就是原子性问题。
JAVA中可以通过各种锁机制来保证原子性。
并发中的有序性
JAVA并发有序性指的是多个线程执行的指令和操作,按照开发的编写的顺序或者预定的顺序执行。多线程并发执行时,可能会发生指令的重排,导致执行的顺序与预期的顺序不一致,从而出现数据竞争和线程安全问题。
JAVA可以通过锁机制或者volatile来保证有序性。