Java高併發-Java內存模型和線程安全

1、原子性

原子性是指一個操做是不可中斷的。即便在多個線程一塊兒執行的時候,一個操做一旦開始,就不會被其它線程干擾。java

i++是原子操做嗎?
不是,包含3個操做:讀i,i=i+1,寫i

32位的機子上讀取64位的long型也不是原子操做

2、有序性

2.1 舉例

在併發時,程序的執行可能會出現亂序git

2.2 步驟

一條指令的執行是能夠分爲不少步驟的:github

  • 取指IF
  • 譯碼和取寄存器操做數ID
  • 執行或者有效地址計算EX
  • 存儲器訪問MEM
  • 寫回WB

流水線執行指令shell

分析:安全

指令分解成不一樣階段
假設一條指令消耗一個CPU時鐘週期
5我的生產一個產品,5我的同時工做

a=b+c
讀b
讀c
計算b+c,結果放到a
寫a

分析:多線程

進行優化,使氣泡儘量的少

分析:併發

調整指令順序,能夠消除氣泡

3、可見性

3.1 定義

可見性是批當一個線程修改了某一個共享變量的值,其餘線程是否可以當即知道這個修改。app

  • 編譯器優化
  • 硬件優化(如寫吸取,批操做)
批量操做,把操做進行積累,只把最終結果寫入

3.2 Java虛擬機層面的可見性

http://hushi55.github.io/2015/01/05/volatile-assembly函數

public class VisibilityTest extends Thread {
	private boolean stop;

	public void run() {
		int i = 0;
		while (!stop) {
			i++;
		}
		System.out.println("finish loop,i=" + i);
	}

	public void stopIt() {
		stop = true;
	}

	public boolean getStop() {
		return stop;
	}

	public static void main(String[] args) throws Exception {
		VisibilityTest v = new VisibilityTest();
		v.start();

		Thread.sleep(1000);
		v.stopIt();
		Thread.sleep(2000);
		System.out.println("finish main");
		System.out.println(v.getStop());
	}
}

分析:oop

stop變量加volatile就不會有這個問題了

4、Happen-Before

5、線程安全的概念

指某個函數、函數庫在多線程環境中被調用時,可以正確地處理各個線程的局部變量 ,使程序功能正確完成。

i++在多線程下訪問的狀況:

相關文章
相關標籤/搜索