void runAllListenersInParallel(final EntryEvent<K, V> _event, List<Listener<K, V>> _listeners) {
    final AtomicInteger _countDown = new AtomicInteger(_listeners.size());
    for (final Listener<K,V> l : _listeners) {
      Runnable r = new Runnable() {
        @Override
        public void run() {
          try {
            l.fire(_event);
          } catch (Throwable t) {
            t.printStackTrace();
          }
          int _done = _countDown.decrementAndGet();
          if (_done == 0) {
            runMoreOnKeyQueueOrStop(_event.getKey());
          }
        }
      };
      executor.execute(r);
    }
  }
void runAllListenersInParallel ( final EntryEvent < K , V > _event , List < Listener < K , V > > _listeners ) { final AtomicInteger _countDown = new AtomicInteger ( _listeners . size ( ) ) ; for ( final Listener < K , V > l : _listeners ) { Runnable r = new Runnable ( ) { @ Override public void run ( ) { try { l . fire ( _event ) ; } catch ( Throwable t ) { t . printStackTrace ( ) ; } int _done = _countDown . decrementAndGet ( ) ; if ( _done == 0 ) { runMoreOnKeyQueueOrStop ( _event . getKey ( ) ) ; } } } ; executor . execute ( r ) ; } }
Pass on runnables to the executor for all listeners. After each event is handled
within the listener we check whether the event is processed by all listeners, by
decrementing a countdown. In case the event is processed completely, we check whether
more is queued up for this key meanwhile.