Merge branch 'Jalview-JS/develop' into merge_js_develop
[jalview.git] / src / jalview / workers / AlignCalcManager.java
index c596f05..ec80576 100644 (file)
@@ -22,10 +22,12 @@ package jalview.workers;
 
 import jalview.api.AlignCalcManagerI;
 import jalview.api.AlignCalcWorkerI;
+import jalview.bin.Cache;
 import jalview.datamodel.AlignmentAnnotation;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
@@ -37,48 +39,49 @@ public class AlignCalcManager implements AlignCalcManagerI
   /*
    * list of registered workers
    */
-  private volatile List<AlignCalcWorkerI> restartable;
+  private final List<AlignCalcWorkerI> restartable = Collections
+          .synchronizedList(new ArrayList<AlignCalcWorkerI>());
 
   /*
    * types of worker _not_ to run (for example, because they have
    * previously thrown errors)
    */
-  private volatile List<Class<? extends AlignCalcWorkerI>> blackList;
+  private final List<Class<? extends AlignCalcWorkerI>> blackList = Collections
+          .synchronizedList(new ArrayList<Class<? extends AlignCalcWorkerI>>());
 
   /*
    * global record of calculations in progress
    */
-  private volatile List<AlignCalcWorkerI> inProgress;
+  private final List<AlignCalcWorkerI> inProgress = Collections
+          .synchronizedList(new ArrayList<AlignCalcWorkerI>());
 
   /*
    * record of calculations pending or in progress in the current context
    */
-  private volatile Map<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>> updating;
+  private final Map<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>> updating =
+          new Hashtable<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>>();
 
   /*
    * workers that have run to completion so are candidates for visual-only 
    * update of their results
    */
-  private HashSet<AlignCalcWorkerI> canUpdate;
+  private HashSet<AlignCalcWorkerI> canUpdate = new HashSet<>();;
 
-  /**
-   * Constructor
-   */
-  public AlignCalcManager()
+  private static boolean listContains(List<AlignCalcWorkerI> upd,
+          AlignCalcWorkerI worker)
   {
-    restartable = Collections
-            .synchronizedList(new ArrayList<AlignCalcWorkerI>());
-    blackList = Collections.synchronizedList(
-            new ArrayList<Class<? extends AlignCalcWorkerI>>());
-    inProgress = Collections
-            .synchronizedList(new ArrayList<AlignCalcWorkerI>());
-    updating = Collections.synchronizedMap(
-            new Hashtable<Class<? extends AlignCalcWorkerI>, List<AlignCalcWorkerI>>());
-    canUpdate = new HashSet<AlignCalcWorkerI>();
+    // avoid use of 'Contains' in case
+    for (AlignCalcWorkerI _otherworker : upd)
+    {
+      if (_otherworker == upd)
+      {
+        return true;
+      }
+    }
+    return false;
   }
-
   @Override
-  public void notifyStart(AlignCalcWorkerI worker)
+  public void notifyStarted(AlignCalcWorkerI worker)
   {
     synchronized (updating)
     {
@@ -90,7 +93,16 @@ public class AlignCalcManager implements AlignCalcManagerI
       }
       synchronized (upd)
       {
-        upd.add(worker);
+        if (listContains(upd, worker))
+        {
+          Cache.log.debug(
+                    "Ignoring second call to notifyStart for worker "
+                            + worker);
+        }
+        else
+        {
+          upd.add(worker);
+        }
       }
     }
   }
@@ -103,22 +115,10 @@ public class AlignCalcManager implements AlignCalcManagerI
   @Override
   public boolean isPending(AlignCalcWorkerI workingClass)
   {
-    List<AlignCalcWorkerI> upd;
     synchronized (updating)
     {
-      upd = updating.get(workingClass.getClass());
-      if (upd == null)
-      {
-        return false;
-      }
-      synchronized (upd)
-      {
-        if (upd.size() > 1)
-        {
-          return true;
-        }
-      }
-      return false;
+      List<AlignCalcWorkerI> upd = updating.get(workingClass.getClass());
+      return upd != null && upd.size() > 1;
     }
   }
 
@@ -127,7 +127,7 @@ public class AlignCalcManager implements AlignCalcManagerI
   {
     synchronized (inProgress)
     {
-      if (inProgress.contains(worker))
+      if (listContains(inProgress, worker))
       {
         return false; // worker is already working, so ask caller to wait around
       }
@@ -144,7 +144,7 @@ public class AlignCalcManager implements AlignCalcManagerI
   {
     synchronized (inProgress)
     {
-      // System.err.println("Worker " + worker + " marked as complete.");
+      Cache.log.debug("Worker " + worker + " marked as complete.");
       inProgress.remove(worker);
       List<AlignCalcWorkerI> upd = updating.get(worker.getClass());
       if (upd != null)
@@ -181,7 +181,15 @@ public class AlignCalcManager implements AlignCalcManagerI
   {
     if (!isDisabled(worker))
     {
-      Thread tw = new Thread(worker);
+      Thread tw = new Thread(() -> {
+        try
+        {
+          worker.run();
+        } catch (Throwable e)
+        {
+          e.printStackTrace();
+        }
+      });
       tw.setName(worker.getClass().toString());
       tw.start();
     }
@@ -216,7 +224,7 @@ public class AlignCalcManager implements AlignCalcManagerI
   {
     synchronized (restartable)
     {
-      if (!restartable.contains(worker))
+      if (!listContains(restartable, worker))
       {
         restartable.add(worker);
       }
@@ -289,7 +297,7 @@ public class AlignCalcManager implements AlignCalcManagerI
   public List<AlignCalcWorkerI> getRegisteredWorkersOfClass(
           Class<? extends AlignCalcWorkerI> workerClass)
   {
-    List<AlignCalcWorkerI> workingClass = new ArrayList<AlignCalcWorkerI>();
+    List<AlignCalcWorkerI> workingClass = new ArrayList<>();
     synchronized (canUpdate)
     {
       for (AlignCalcWorkerI worker : canUpdate)
@@ -313,11 +321,11 @@ public class AlignCalcManager implements AlignCalcManagerI
   }
 
   @Override
-  public void removeRegisteredWorkersOfClass(
+  public void removeWorkersOfClass(
           Class<? extends AlignCalcWorkerI> typeToRemove)
   {
-    List<AlignCalcWorkerI> removable = new ArrayList<AlignCalcWorkerI>();
-    Set<AlignCalcWorkerI> toremovannot = new HashSet<AlignCalcWorkerI>();
+    List<AlignCalcWorkerI> removable = new ArrayList<>();
+    Set<AlignCalcWorkerI> toremovannot = new HashSet<>();
     synchronized (restartable)
     {
       for (AlignCalcWorkerI worker : restartable)
@@ -367,7 +375,7 @@ public class AlignCalcManager implements AlignCalcManagerI
      * first just find those to remove (to avoid
      * ConcurrentModificationException)
      */
-    List<AlignCalcWorkerI> toRemove = new ArrayList<AlignCalcWorkerI>();
+    List<AlignCalcWorkerI> toRemove = new ArrayList<>();
     for (AlignCalcWorkerI worker : restartable)
     {
       if (worker.involves(ann))