NoSuchElementException even after check
java
Solution
`LinkedList` is not thread-safe, so you need external synchronization if you access a `Linkedlist` on more than one thread. This synchronization is on some object (a `synchronized` method is just shorthand for "synchronize on `this`"), and both the gets and the puts must be synchronized on the same object. You're definitely doing that here, since you create a new thread for each `SmartPhone`, and then access that phone's `LinkedList` from there.
If one thread puts into the list while synchronized on `someObject1`, and then another thread reads that list while synchronized on `someObject2`, then this does not count as external synchronization -- the code is still broken.
Even if you used a thread-safe collection, it'd be possible to hit this exception if multiple threads are emptying the queue at the same time. For instance, imagine this:
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
You should use `BlockingQueue`, whose `poll()` method will return `null` if there are no more elements in the list. Keep pulling until you get a `null`, and then break the loop.
Problem
``` 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(); } ``` And log: ``` 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) ``` line 118 points to: ``` task=tasks.poll(); ``` How to solve this? Queue is LinkedList implemenation if that makes a difference.