Lolmewn Lolmewn - 13 days ago 5
Java Question

NegativeArraySizeException on a HashMap

For some reason, my program suddenly throws a

NegativeArraySizeException
after running for a while. The code that throws it is behind a command, which I've entered before the exception is thrown.

The code I'm using is mostly for debug purposes, and is the following:

final HashMap<String, Integer> busy = new HashMap<>();
//this map gets filled and emptied in threads

System.out.println("Busy tables: " + Arrays.toString(this.busy.keySet().toArray()));
System.out.println("Time busy: " + Arrays.toString(this.busy.values().toArray()));
//map gets read (from the input handler thread)


The exception is thrown on the first
System.out.println()
line, but I can imagine it being thrown on the other one too if it'd continued running.

Could it be some sort of Threading issue or could the cause be somewhere else?

Google gave me (for the first time in ages) no usable results. How can a Set have a negative size anyway?

Edit: The exception:

Exception in thread "Thread-1" java.lang.NegativeArraySizeException
at java.util.AbstractCollection.toArray(Unknown Source)
at nl.lolmewn.statsglobal.Main.handleInput(Main.java:61)
at nl.lolmewn.statsglobal.Main.access$000(Main.java:20)
at nl.lolmewn.statsglobal.Main$1.run(Main.java:200)
at java.lang.Thread.run(Unknown Source)

Answer

Without more information about your code, I would consider unprotected multi-threaded accesses to the HashMap object to be the prime suspect. HashMap, contrary to Hashtable, is not synchronized and needs explicit locks to work in a multi-threaded environment, either directly or through the sets returned via keySet() or entrySet().

Failing to do that can create a lot of interesting side-effects due to the HashMap being in a inconsistent internal state. I would suggest using a debugger to break on that exception and have a better look at what is going on.