多線程的三大特性:原子性、可見性和有序性。
原子性
原子性是指一個操作或者多個操作,一旦開始就不會被其他線程干擾,即使是在多個線程一起執行的情況下也不會被干擾。或者不執行。
原子性主要是為了保證數據一致,線程安全問題。
可見性
可見性是指當一個線程修改了某一個共享變量的值,其他線程是否能夠立即知道這個修改。
對于串行程序來說,可見性問題是不存在的。因為你在任何一個操作步驟中修改了某個變量,那么后續的步驟中,讀取這個變量的值一定是修改后的新值。
對于并行程序來說就可能存在了。如果存在兩個線程:線程1、線程2,共享變量:t,線程1 為了優化獲取共享變量速度將共享變量存放在緩存中,此時線程2 對共享變量進行修改,那么線程1 又無法意識到這個改動,依然從緩沖中獲取數據。因此,就產生了可見性問題。
除了上述提到的緩存優化會導致可見性問題,指令重拍以及編輯器的優化,都有可能導致一個線程的修改不會立即被其他線程察覺。
有序性
有序性問題可能是三個問題中最難理解的了。對于一個線程的執行代碼而言,是一次執行的。但是,在并發是,程序的執行可能就會出現亂序。
public class OrderTest {int a = 0;boolean flag = false;public void writer(){a = 1;flag = true;}public void reader(){if (!flag){System.out.println(a);}}}
假設有兩個線程:A、B,線程A 先執行 writer 方法,接著線程B 執行 reader 方法,此時線程B 不一定能打印 a 。