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;
/*
* 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)
{
}
synchronized (upd)
{
- upd.add(worker);
+ if (listContains(upd, worker))
+ {
+ Cache.log.debug(
+ "Ignoring second call to notifyStart for worker "
+ + worker);
+ }
+ else
+ {
+ upd.add(worker);
+ }
}
}
}
@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;
}
}
{
synchronized (inProgress)
{
- if (inProgress.contains(worker))
+ if (listContains(inProgress, worker))
{
return false; // worker is already working, so ask caller to wait around
}
{
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)
{
if (!isDisabled(worker))
{
- Thread tw = new Thread(worker);
+ Thread tw = new Thread(() -> {
+ try
+ {
+ worker.run();
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ });
tw.setName(worker.getClass().toString());
tw.start();
}
{
synchronized (restartable)
{
- if (!restartable.contains(worker))
+ if (!listContains(restartable, worker))
{
restartable.add(worker);
}
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)
}
@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)
* 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))