We are getting this exception which seems impossible given our code... We add items to a static linked list and we start a thread to process items added on those lists. If the static thread is dead or null when adding items to the list we start it off again. The thread makes itself null once all items are processed.
See small snippet below
Code:
public class LiveKPIUpdates extends Thread {
private static final int MAX_QUEUE_SIZE = 1000;
private static LinkedList < UpdateLine > highQueue = new LinkedList < UpdateLine > ();
private static LinkedList < UpdateLine > lowQueue = new LinkedList < UpdateLine > ();
private static UpdateThread updateThread = null;
/**
* Thread to process live update queues.
* High priority items are processed first.
*/
static class UpdateThread extends Thread {
@Override
public void run() {
while (!highQueue.isEmpty() || !lowQueue.isEmpty()) {
UpdateLine update = !highQueue.isEmpty() ? highQueue.removeFirst() : lowQueue.removeFirst(); // <<<<< !!! EXCEPTION HAPPENS HERE... Why/How? !!! >>>>>>>>>>>>>>>
//Do stuff with update
}
updateThread = null;
}
}
/**
* Adds the live update to a queue to be processed.
* If the queue is full, the update may be ignored.
*
* @param appender The machine who sent these lines
* @param lines The lines the machine sent. (Can be tray file or machine log lines)
*/
synchronized public static void updateKPIWithMachineLines(AppenderID appender,
String fileName, Date fileDate, LinkedList < String > lines) throws ParseException, SQLException {
for (String line: lines) {
if (line.startsWith("something...")) {
if (highQueue.size() < MAX_QUEUE_SIZE) {
highQueue.add(new UpdateLine(appender, fileName, fileDate, line));
} else {
TLSystemAction.log("Live updates high priority queue full", appender);
}
} else {
if (lowQueue.size() < MAX_QUEUE_SIZE) {
lowQueue.add(new UpdateLine(appender, fileName, fileDate, line));
} else {
TLSystemAction.log("Live updates low priority queue full", appender);
}
}
}
if (updateThread == null) {
updateThread = new UpdateThread();
updateThread.start();
} else if (!updateThread.isAlive()) {
updateThread.interrupt();
updateThread = new UpdateThread();
updateThread.start();
}
}
Exception:
[#|2015-03-12T11:12:10.614+1300|SEVERE|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=617736;_ThreadName=Thread-1;|java.util.NoSuchElementException
at java.util.LinkedList.remove(LinkedList.java:788)
at java.util.LinkedList.removeFirst(LinkedList.java:134)
at api.tl.put.LiveKPIUpdates$UpdateThread.run(LiveKPIUpdates.java:67)
EDIT: I am more interested in how it is possible for it to get to the lowQueue.removeFirst() if lowQueue is empty. The logic seems to protect from that.