Search code examples
javaatomicconcurrenthashmap

Counting the number of exceptions happening in catch block


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());
}              
}

Solution

  • 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.