首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NoSuchElementException即使在检查之后也是如此

NoSuchElementException即使在检查之后也是如此
EN

Stack Overflow用户
提问于 2013-07-18 00:47:07
回答 1查看 5.8K关注 0票数 3
代码语言:javascript
复制
for (final ArrayList<SmartPhone> smartPhones : smartPhonesCluster) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            for (SmartPhone smartPhone : smartPhones) {
                Queue<SmartPhoneTask> tasks = smartPhone.getSystem()
                                                        .getTaskQue();
                SmartPhoneTask task = null;
                assert tasks != null;
                try {
                    while (!tasks.isEmpty()) {
                        task = tasks.poll(); // This is the line throwing the exception (GlobalNetwork.java:118)
                        assert task != null;
                        task.execute();
                        task.onTaskComplete();
                    }
                } catch (RuntimeException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
}

和日志:

代码语言:javascript
复制
java.util.NoSuchElementException
    at java.util.LinkedList.remove(LinkedList.java:788)
    at java.util.LinkedList.removeFirst(LinkedList.java:134)
    at java.util.LinkedList.poll(LinkedList.java:470)
    at com.wtsang02.reu.botnet.network.GlobalNetwork$1.run(GlobalNetwork.java:118)
    at java.lang.Thread.run(Thread.java:662)
java.lang.NullPointerException
Exception in thread "Thread-299" java.lang.AssertionError
    at com.wtsang02.reu.botnet.network.GlobalNetwork$1.run(GlobalNetwork.java:119)
    at java.lang.Thread.run(Thread.java:662)

第118行指向:

代码语言:javascript
复制
task=tasks.poll();

如何解决这个问题?队列是LinkedList的实现,如果有区别的话。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-18 01:05:45

LinkedList不是线程安全的,因此如果您在多个线程上访问Linkedlist,则需要外部同步。这种同步是在某个对象上进行的( synchronized方法只是"synchronize on this“的简写),gets和puts必须在同一个对象上同步。您在这里肯定会这样做,因为您为每个SmartPhone创建了一个新线程,然后从那里访问该电话的LinkedList

如果一个线程在someObject1上同步时放入列表,然后另一个线程在someObject2上同步时读取该列表,那么这不算外部同步--代码仍然是损坏的。

即使您使用线程安全的集合,如果多个线程同时清空队列,也可能遇到此异常。例如,想象一下:

代码语言:javascript
复制
thread A: put e into queue1
thread B: queue1.isEmpty()? No, so go on
thread C: queue1.isEmpty()? No, so go on
thread B: queue1.poll() // works
thread C: queue1.poll() // NoSuchElementException

您应该使用BlockingQueue,如果列表中没有更多的元素,那么它的poll()方法将返回null。继续拉直到你得到一个null,然后打破循环。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17705658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档