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();
}
Run Code Online (Sandbox Code Playgroud)
并记录:
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)
Run Code Online (Sandbox Code Playgroud)
118行指向:
task=tasks.poll();
Run Code Online (Sandbox Code Playgroud)
怎么解决这个?如果这会产生影响,Queue就是LinkedList实现.
LinkedList不是线程安全的,因此如果您访问Linkedlist多个线程,则需要外部同步.此同步在某个对象上(synchronized方法只是"同步this"的简写),并且必须在同一对象上同步gets和puts .你肯定是在这里做的,因为你为每个人创建一个新的线程SmartPhone,然后LinkedList从那里访问那个手机.
如果一个线程是置于列表,而同步上someObject1,然后另一个线程读取列表,而在同步someObject2,那么这并不能算作外部同步-代码仍然是断开的.
即使您使用了线程安全的集合,如果多个线程同时清空队列,也可能会遇到此异常.例如,想象一下:
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
Run Code Online (Sandbox Code Playgroud)
你应该使用BlockingQueue,如果列表中没有更多的元素,它的poll()方法将返回null.继续拉,直到你得到一个null,然后打破循环.
| 归档时间: |
|
| 查看次数: |
4718 次 |
| 最近记录: |