I am trying to collect all the counts of exception happening and the name of exception in a ConcurrentHashMap
so that I should be aware of how many times this exception has occurred.
So in my catch block I have map that will keep on adding the name of exception and there total count occurrence.
Below is my code which I have modified to always throw SQL Exception
everytime for the testing purpose so that I can see the count of exception is accurate or not.
So certain scenario-
1) If I am choosing number of threads as 10
and number of tasks as 50
, then in that map, I can see 500 exception for that particular String
2)But If I am choosing number of threads as 40
and number of tasks as 500
then I am not seeing 20000
exceptions in that map, it shows around 19000
.
My question is why? What wrong I am doing here?
class Task implements Runnable {
public static final AtomicInteger counter_exception = new AtomicInteger(0);
public static ConcurrentHashMap<String, Integer> exceptionMap = new ConcurrentHashMap<String, Integer>();
@Override
public void run() {
try {
//Making a db connection and then executing the SQL-
} catch (SQLException e) {
exceptionMap.put(e.getCause().toString(), counter_exception.incrementAndGet());
} catch (Exception e) {
}
}
}
Updated:
If I have something like this- I am getting Null Pointer Exception
for 40 threads and 4000 taks. Why?
catch (SQLException e) {
synchronized(this) {
exceptionMap.put(e.getCause().toString(), counter_exception.incrementAndGet());
}
}
Maybe something like this is happening:
Task 1-500: Catch exceptions, prepare to call exceptionMap.put
, get a number from counter_exception.incrementAndGet()
that is passed to said method
Task 500: Has number 500 from the atomic integer counter, is scheduled so its exceptionMap.put
runs first
Task 1: Has number 1 from the atomic integer counter, is scheduled so its exceptionMap.put
runs last
Now even though the counter is 500 and we had 500 exceptions, the exception message gets associated with 1 because that was executed the most recently.