本案例來源於java zone社區,因爲源代碼裏面存在一些本身開發的註解,我暫時沒找到相關的文檔,因此我作了一些修改。用的都是java SDK的API。
關於概念:java
進入正題,若是能夠從多個線程調用全部方法而沒有外部同步,則類是線程安全的。爲了實現這一點,線程安全方法必須是原子的,例如,其餘線程只能看到方法以前或以後調用之間的狀態。如下示例說明了爲何線程安全方法必須是原子的:git
public class TR extends FanLibrary { private volatile int i = 0; public void ss() { sleep(100);//爲了更容易出現效果 i++; } @Before public void be() { output("before"); } @Test public void sdfa() throws InterruptedException { Thread first = new Thread(() -> { ss(); }); Thread second = new Thread(() -> { ss(); }); first.start(); second.start(); first.join(); second.join(); output(i); } @After public void ds() { output("after"); } }
控制檯輸出,如下內容可能會出現,代碼中sleep(100)的緣由:api
INFO-> before INFO-> 1 INFO-> after
其中「i++;」至關於「i = i + 1;」包含了「i + 1」和「i =」兩個過程,不屬於原子操做,因此在多線程訪問該方法的時候是不安全的安全
當兩個線程同時獲取到i = 0的值時,若是此時都沒有執行到「i =」這個步驟的時候,那麼兩個線程等號右邊都是1,而後先後執行「i = 1」 這個操做,至關於i最終被兩次賦值爲1,因此最終「i = 1」markdown