如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程啟動並執行結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是安全執行緒的。
比如一個 ArrayList 類,在添加一個元素的時候,它可能會有兩步來完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。
在單線程啟動並執行情況下,如果 Size = 0,添加一個元素後,此元素在位置 0,而且 Size=1;
而如果是在多線程情況下,比如有兩個線程,線程 A 先將元素存放在位置 0。但是此時 CPU 調度線程A暫停,線程 B 得到啟動並執行機會。線程B也向此 ArrayList 添加元素,因為此時 Size 仍然等於 0 (注意哦,我們假設的是添加一個元素是要兩個步驟哦,而線程A僅僅完成了步驟1),所以線程B也將元素存放在位置0。然後線程A和線程B都繼續運行,都增加 Size 的值。
那好,現在我們來看看 ArrayList 的情況,元素實際上只有一個,存放在位置 0,而 Size 卻等於 2。這就是“線程不安全”了。
如何做到安全執行緒:
四種方式 sychronized關鍵字
1. sychronized method(){}
2. sychronized (objectReference) {/*block*/}
3. static synchronized method(){}
4. sychronized(classname.class)
其中1和2是代表鎖當前對象,即一個對象就一個鎖,3和4代表鎖這個類,即這個類的鎖。要注意的是sychronized method()不是鎖這個函數,而是鎖對象,即:如果這個類中有兩個方法都是sychronized,那麼只要有兩個線程共用一個該類的reference,每個調用這兩個方法之一,不管是否同一個方法,都會用這個對象鎖進行同步。
注意:long 和double是簡單類型中兩個特殊的咚咚:java讀他們要讀兩次,所以需要同步。