2011-04-21 81 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

相关问题