允許被多個線程同時執行的代碼稱作線程安全的代碼。線程安全的代碼不包含競態條件。當多個線程同時更新共享資源時會引發競態條件。因此,了解 Java 線程執行時共享了什么資源很重要。
一、局部變量(函數內定義)
局部變量存儲在線程自己的棧中。也就是說,局部變量永遠也不會被多個線程共享。
1、基礎類型的局部變量
線程安全
2、局部的對象引用
對象的局部引用和基礎類型的局部變量不太一樣。盡管引用本身沒有被共享,但引用所指的對象並沒有存儲在線程的棧內。所有的對象都存在共享堆中;
如果在某個方法中創建的對象不會逃逸出(即該對象不會被其它方法獲得,也不會被非局部變量引用到)該方法,那么它就是線程安全的。
二、對象成員
對象成員存儲在堆上。如果兩個線程同時更新同一個對象的同一個成員,那這個代碼就不是線程安全的。
三、確保線程安全
1、創建不可變的共享對象來保證對象在線程間共享時不會被修改,從而實現線程安全;
2、一個對象是線程安全的不可變對象,指向這個對象的引用也可能不是線程安全的,即引用不是線程安全的,通過同步可以解決;