This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
List list = new ArrayList(); | |
void main() throws InterruptedException { | |
Thread thread1 = new Thread(() -> { foo(); }); | |
Thread thread2 = new Thread(() -> { foo(); }); | |
thread1.start(); thread2.start(); | |
thread1.join(); thread2.join(); | |
Collections.sort(list); | |
} | |
void foo() { | |
for (int i=0; i<100; i++) | |
bar(); | |
} | |
void bar() { | |
list.add(new Something()); | |
} |
看起來沒什麼問題,但詭異的是「有時候」第8行會拋出NullPointerException,
會有這問題是因為要排序的list有null元素,
但是明明在bar()裡面每次都有new一個物件並加入list中,
為什麼還會產生NullPointerException呢?
後來我試著在第7行後印出list的每個元素,發現真的有幾個元素是null。
我也試著在每次執行後印出list的大小,
預期應該要得到200這個數字,但神奇的是每次執行的結果都不同。
後來就想到有可能是執行緒同步的問題,
最後把bar()設定為synchronized後問題就解決了。
我猜測是foo()在同時存取bar()的時候,可能會造成其中一個正在執行的bar()被打斷,
或著是在new Something()時還沒結束,就被打斷,造成加入null元素到list的狀況發生。
沒有留言:
張貼留言