2016-01-06

Collections.sort() throws NullPointerException

這幾天寫程式時碰到Collections.sort()拋出NullPointerException的問題,大概的程式碼如下:

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的狀況發生。

沒有留言:

張貼留言