Fix data race in MultiProgressMonitor.

Access to Task.count should be synchronized.

Change-Id: I1cedac1f747e5d35ba044fd0557d6a03723f7b09
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/MultiProgressMonitor.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/MultiProgressMonitor.java
index d081fe6..414ba5f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/MultiProgressMonitor.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/MultiProgressMonitor.java
@@ -96,6 +96,29 @@
       }
     }
 
+    synchronized void format(StringBuilder s, boolean first) {
+      if (count == 0) {
+        return;
+      }
+
+      if (!first) {
+        s.append(',');
+      }
+      s.append(' ');
+
+      if (!Strings.isNullOrEmpty(name)) {
+        s.append(name).append(": ");
+      }
+
+      if (total == UNKNOWN) {
+        s.append(count);
+      } else {
+        s.append(String.format("%d%% (%d/%d)",
+            count * 100 / total,
+            count, total));
+      }
+    }
+
     /**
      * Indicate that this sub-task is finished.
      * <p>
@@ -316,32 +339,9 @@
     StringBuilder s = new StringBuilder().append("\r").append(taskName)
         .append(':');
 
-    if (!tasks.isEmpty()) {
-      boolean first = true;
-      for (Task t : tasks) {
-        int count = t.count;
-        if (count == 0) {
-          continue;
-        }
-
-        if (!first) {
-          s.append(',');
-        } else {
-          first = false;
-        }
-
-        s.append(' ');
-        if (!Strings.isNullOrEmpty(t.name)) {
-          s.append(t.name).append(": ");
-        }
-        if (t.total == UNKNOWN) {
-          s.append(count);
-        } else {
-          s.append(String.format("%d%% (%d/%d)",
-              count * 100 / t.total,
-              count, t.total));
-        }
-      }
+    int firstLength = s.length();
+    for (Task t : tasks) {
+      t.format(s, s.length() == firstLength);
     }
 
     if (spinnerState != NO_SPINNER) {