Fix for ONOS-2572 - Excessive events delivered by AbstractAccumulator

- add synchronization to prevent prematurely scheduling a batch that
  isn't full.

Change-Id: I07d53ef4d81211909a6fcdd98bc937b49c7c4cca
diff --git a/utils/misc/src/main/java/org/onlab/util/AbstractAccumulator.java b/utils/misc/src/main/java/org/onlab/util/AbstractAccumulator.java
index ef692c7..e9e3cc8 100644
--- a/utils/misc/src/main/java/org/onlab/util/AbstractAccumulator.java
+++ b/utils/misc/src/main/java/org/onlab/util/AbstractAccumulator.java
@@ -40,8 +40,8 @@
     private final int maxBatchMillis;
     private final int maxIdleMillis;
 
-    private TimerTask idleTask = new ProcessorTask();
-    private TimerTask maxTask = new ProcessorTask();
+    private volatile TimerTask idleTask = new ProcessorTask();
+    private volatile TimerTask maxTask = new ProcessorTask();
 
     private List<T> items = Lists.newArrayList();
 
@@ -108,10 +108,14 @@
     private class ProcessorTask extends TimerTask {
         @Override
         public void run() {
-            idleTask = cancelIfActive(idleTask);
+            synchronized (AbstractAccumulator.this) {
+                idleTask = cancelIfActive(idleTask);
+            }
             if (isReady()) {
                 try {
-                    maxTask = cancelIfActive(maxTask);
+                    synchronized (AbstractAccumulator.this) {
+                        maxTask = cancelIfActive(maxTask);
+                    }
                     List<T> items = finalizeCurrentBatch();
                     if (!items.isEmpty()) {
                         processItems(items);
@@ -120,7 +124,9 @@
                     log.warn("Unable to process batch due to {}", e);
                 }
             } else {
-                idleTask = schedule(maxIdleMillis);
+                synchronized (AbstractAccumulator.this) {
+                    idleTask = schedule(maxIdleMillis);
+                }
             }
         }
     }