2011-04-21 132 views
0

我使用Java 6 Collecetions API。我需要一個應該只有N個元素的集合。我的意思是,如果我添加新的元素並且集合已經有N個元素,那麼最後一個元素應該被刪除,並且新的元素將添加到集合的頭部。我有以下代碼片段來做到這一點:LinkedList.pollLast()拋出NullPointerException異常

class A { 

    int N = 100; 
    Deque dq = new LinkedList(); 

    void add(Object o) { 
    synchronized (o) { 
     if (dq.size() == N) { 
     dq.pollLast(); 
     } 
     dq.add(o); 
    } 
    } 

    Deque getDq() { 
    return new LinkedList(dq); 
    } 
} 

與類型A的對象可以在同一時間訪問許多用戶添加新元素。在實踐中我得到NullPointerException異常與它:

Caused by: java.lang.NullPointerException 
    at java.util.LinkedList.remove(LinkedList.java:790) 
    at java.util.LinkedList.removeLast(LinkedList.java:144) 
    at java.util.LinkedList.pollLast(LinkedList.java:573) 
    at A.add(A.java:9) 

Deque.pollLast()的合同並沒有說明任何的NullPointerException:

獲取並移除此列表的最後一個元素 ,或返回null如果這個 列表是空的。

同步添加元素。

有誰知道異常的原因是什麼?

感謝您的任何想法

+1

你應該一個共同的對象上進行同步(即列表,'this'或一些特殊的鎖定對象),而不是在參數。不知道這是否會導致你的問題。 – 2011-04-21 10:59:31

+2

是你使用的代碼嗎?如果是這樣,你運行哪種語言? 'Dequeu'沒有公共領域'大小',你可以像這樣訪問。 – 2011-04-21 11:01:53

+2

@user:這是一種方法,你可以不用'()'來訪問它。我知道這可能是一個錯字,但這意味着您向我們顯示的代碼是**而不是代碼有問題。請製作[SSCCE](http://sscce.org/)。 – 2011-04-21 11:04:35

回答

3

我猜sycronization是在錯誤的對象上完成的!它應該是dq但不是o

... synchronized (dg) { ... 
+0

我同意這一點。您並未通過鎖定您嘗試添加/刪除的元素來阻止對Deque的同時訪問。 – merxbj 2011-04-21 11:21:12

0

this javadoc它說

Removes and returns the last element from this list. 

首先它會刪除對象,所以如果它爲null,則拋出NullPointerException異常:

所以請加(..)方法同步,檢查大小之前dq.pollLast();

+0

[LinkedList.pollLast()](http://download.oracle.com/javase/6/docs/api/java/util/LinkedList.html#pollLast())在代碼很好地同步時不會引發異常: – Raman 2011-04-21 15:33:43

1

我已經運行使用下面的測試

A a = new A(); 
    for (int i = 0; i < 200; i++) 
    { 
     a.add(i); 
    } 
    System.out.println(a.dq); 

你的代碼加入而這一切似乎正常工作。當你得到NPE時,你能否提供關於申請狀態的更多細節?你試圖添加什麼對象?當時的出隊狀態是什麼?

另外,你提到

如果我添加了新的元素和收藏 已經有N個元素比去年 元素應該被去掉,新的 中收集的頭部添加

你的代碼不會那樣做。現在,它增加了收藏的尾部。將它添加到頭部,改變

dq.add(o) 

dq.addFirst(o) 
+0

我認爲這裏的真正問題是同步,而不是算法本身。它也可能是錯誤的。 – merxbj 2011-04-21 11:27:00

+0

非常真實。我試圖排除算法問題,並提示有關如何使用dq以及它的狀態的更多信息。可能dq通過getDq()訪問器(正如其他人提到的)以某種其他非同步方式使用。 – tschaible 2011-04-21 11:39:11

相關問題