From d6509fcf3a8cc90616e18cb22cec97f85c722bb8 Mon Sep 17 00:00:00 2001 From: jprocter Date: Tue, 12 Jun 2012 12:35:56 +0100 Subject: [PATCH] JAL-1115 refactor base collection for Alignment from Vector to locally synchronized List --- src/jalview/analysis/AlignmentSorter.java | 68 ++++++---- src/jalview/analysis/CrossRef.java | 7 +- src/jalview/appletgui/AlignFrame.java | 1 + src/jalview/appletgui/PaintRefresher.java | 7 +- src/jalview/commands/EditCommand.java | 6 +- src/jalview/datamodel/Alignment.java | 204 ++++++++++++++++------------ src/jalview/datamodel/AlignmentI.java | 7 +- src/jalview/datamodel/HiddenSequences.java | 32 +++-- src/jalview/gui/AlignFrame.java | 5 +- src/jalview/gui/PaintRefresher.java | 12 +- src/jalview/gui/SequenceFetcher.java | 18 +-- src/jalview/io/VamsasAppDatastore.java | 20 ++- src/jalview/io/vamsas/Tree.java | 7 +- 13 files changed, 229 insertions(+), 165 deletions(-) diff --git a/src/jalview/analysis/AlignmentSorter.java b/src/jalview/analysis/AlignmentSorter.java index b84eeaf..3c3feb3 100755 --- a/src/jalview/analysis/AlignmentSorter.java +++ b/src/jalview/analysis/AlignmentSorter.java @@ -146,11 +146,15 @@ public class AlignmentSorter } // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work - for (int i = 0; i < len; i++) + List asq; + synchronized (asq = align.getSequences()) { - // SequenceI tmp = seqs[i]; - align.getSequences().setElementAt(seqs[nSeq - i - 1], i); - align.getSequences().setElementAt(seqs[i], nSeq - i - 1); + for (int i = 0; i < len; i++) + { + // SequenceI tmp = seqs[i]; + asq.set(i, seqs[nSeq - i - 1]); + asq.set(nSeq - i - 1, seqs[i]); + } } } @@ -178,24 +182,26 @@ public class AlignmentSorter public static void setOrder(AlignmentI align, SequenceI[] seqs) { // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work - Vector algn = align.getSequences(); - Vector tmp = new Vector(); - - for (int i = 0; i < seqs.length; i++) + List algn; + synchronized (algn = align.getSequences()) { - if (algn.contains(seqs[i])) + List tmp = new ArrayList(); + + for (int i = 0; i < seqs.length; i++) { - tmp.addElement(seqs[i]); + if (algn.contains(seqs[i])) + { + tmp.add(seqs[i]); + } } - } - algn.removeAllElements(); - // User may have hidden seqs, then clicked undo or redo - for (int i = 0; i < tmp.size(); i++) - { - algn.addElement(tmp.elementAt(i)); + algn.clear(); + // User may have hidden seqs, then clicked undo or redo + for (int i = 0; i < tmp.size(); i++) + { + algn.add(tmp.get(i)); + } } - } /** @@ -357,18 +363,20 @@ public class AlignmentSorter } /** - * DOCUMENT ME! - * + * Select sequences in order from tmp that is present in mask, and any + * remaining seqeunces in mask not in tmp + * * @param tmp - * DOCUMENT ME! + * thread safe collection of sequences * @param mask - * DOCUMENT ME! - * - * @return DOCUMENT ME! + * thread safe collection of sequences + * + * @return intersect(tmp,mask)+intersect(complement(tmp),mask) */ - private static SequenceI[] vectorSubsetToArray(Vector tmp, Vector mask) + private static SequenceI[] vectorSubsetToArray(List tmp, + List mask) { - Vector seqs = new Vector(); + ArrayList seqs = new ArrayList(); int i, idx; boolean[] tmask = new boolean[mask.size()]; @@ -379,12 +387,12 @@ public class AlignmentSorter for (i = 0; i < tmp.size(); i++) { - Object sq = tmp.elementAt(i); + SequenceI sq = tmp.get(i); idx = mask.indexOf(sq); if (idx > -1 && tmask[idx]) { tmask[idx] = false; - seqs.addElement(sq); + seqs.add(sq); } } @@ -392,11 +400,11 @@ public class AlignmentSorter { if (tmask[i]) { - seqs.addElement(mask.elementAt(i)); + seqs.add(mask.get(i)); } } - return vectorToArray(seqs); + return seqs.toArray(new SequenceI[seqs.size()]); } /** @@ -542,7 +550,7 @@ public class AlignmentSorter * @return DOCUMENT ME! */ private static Vector _sortByTree(SequenceNode node, Vector tmp, - Vector seqset) + List seqset) { if (node == null) { diff --git a/src/jalview/analysis/CrossRef.java b/src/jalview/analysis/CrossRef.java index 6298505..34bfa61 100644 --- a/src/jalview/analysis/CrossRef.java +++ b/src/jalview/analysis/CrossRef.java @@ -18,6 +18,7 @@ package jalview.analysis; import java.util.Enumeration; +import java.util.List; import java.util.Vector; import java.util.Hashtable; @@ -486,10 +487,10 @@ public class CrossRef System.err.println("Empty dataset sequence set - NO VECTOR"); return false; } - Enumeration e = dataset.getSequences().elements(); - while (e.hasMoreElements()) + List ds; + synchronized (ds=dataset.getSequences()) { - SequenceI nxt = (SequenceI) e.nextElement(); + for (SequenceI nxt:ds) if (nxt != null) { if (nxt.getDatasetSequence() != null) diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java index fce736f..9e5c4fb 100644 --- a/src/jalview/appletgui/AlignFrame.java +++ b/src/jalview/appletgui/AlignFrame.java @@ -35,6 +35,7 @@ import jalview.datamodel.AlignmentOrder; import jalview.datamodel.ColumnSelection; import jalview.datamodel.PDBEntry; import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.io.AnnotationFile; diff --git a/src/jalview/appletgui/PaintRefresher.java b/src/jalview/appletgui/PaintRefresher.java index 25e529b..fbdea9d 100755 --- a/src/jalview/appletgui/PaintRefresher.java +++ b/src/jalview/appletgui/PaintRefresher.java @@ -18,6 +18,7 @@ package jalview.appletgui; import java.util.*; +import java.util.List; import java.awt.*; @@ -183,7 +184,11 @@ public class PaintRefresher { if (i < comp.getHeight()) { - comp.getSequences().insertElementAt(a1[i], i); + // TODO: the following does not trigger any recalculation of height/etc, or maintain the dataset + List alsq; + synchronized (alsq=comp.getSequences()) { + alsq.add(i, a1[i]); + } } else { diff --git a/src/jalview/commands/EditCommand.java b/src/jalview/commands/EditCommand.java index 76ddbac..a8aa886 100644 --- a/src/jalview/commands/EditCommand.java +++ b/src/jalview/commands/EditCommand.java @@ -344,8 +344,10 @@ public class EditCommand implements CommandI // read it to the alignment if (command.alIndex[i] < command.al.getHeight()) { - command.al.getSequences().insertElementAt(command.seqs[i], - command.alIndex[i]); + List sequences; + synchronized (sequences=command.al.getSequences()) { + sequences.add(command.alIndex[i], command.seqs[i]); + } } else { diff --git a/src/jalview/datamodel/Alignment.java b/src/jalview/datamodel/Alignment.java index 23fe057..f9de115 100755 --- a/src/jalview/datamodel/Alignment.java +++ b/src/jalview/datamodel/Alignment.java @@ -32,9 +32,10 @@ public class Alignment implements AlignmentI { protected Alignment dataset; - protected Vector sequences; + protected List sequences; - protected Vector groups = new Vector(); + protected List groups = java.util.Collections + .synchronizedList(new ArrayList()); protected char gapCharacter = '-'; @@ -66,11 +67,12 @@ public class Alignment implements AlignmentI type = PROTEIN; } - sequences = new Vector(); + sequences = java.util.Collections + .synchronizedList(new ArrayList()); for (i = 0; i < seqs.length; i++) { - sequences.addElement(seqs[i]); + sequences.add(seqs[i]); } } @@ -118,7 +120,8 @@ public class Alignment implements AlignmentI * * @return DOCUMENT ME! */ - public Vector getSequences() + @Override + public List getSequences() { return sequences; } @@ -134,12 +137,10 @@ public class Alignment implements AlignmentI { if (sequences == null) return null; - SequenceI[] reply = new SequenceI[sequences.size()]; - for (int i = 0; i < sequences.size(); i++) + synchronized (sequences) { - reply[i] = (SequenceI) sequences.elementAt(i); + return sequences.toArray(new SequenceI[sequences.size()]); } - return reply; } /** @@ -152,11 +153,13 @@ public class Alignment implements AlignmentI */ public SequenceI getSequenceAt(int i) { - if (i>-1 && i < sequences.size()) + synchronized (sequences) { - return (SequenceI) sequences.elementAt(i); + if (i > -1 && i < sequences.size()) + { + return sequences.get(i); + } } - return null; } @@ -189,7 +192,10 @@ public class Alignment implements AlignmentI } else { - sequences.addElement(snew); + synchronized (sequences) + { + sequences.add(snew); + } } if (hiddenSequences != null) hiddenSequences.adjustHeightSequenceAdded(); @@ -203,9 +209,11 @@ public class Alignment implements AlignmentI public void setSequenceAt(int i, SequenceI snew) { SequenceI oldseq = getSequenceAt(i); - deleteSequence(oldseq); - - sequences.setElementAt(snew, i); + deleteSequence(i); + synchronized (sequences) + { + sequences.set(i, snew); + } } /** @@ -263,24 +271,34 @@ public class Alignment implements AlignmentI { if (i > -1 && i < getHeight()) { - sequences.removeElementAt(i); + synchronized (sequences) + { + sequences.remove(i); + } hiddenSequences.adjustHeightSequenceDeleted(i); } } - /** */ + /* + * (non-Javadoc) + * + * @see jalview.datamodel.AlignmentI#findGroup(jalview.datamodel.SequenceI) + */ + @Override public SequenceGroup findGroup(SequenceI s) { - for (int i = 0; i < this.groups.size(); i++) + synchronized (groups) { - SequenceGroup sg = (SequenceGroup) groups.elementAt(i); - - if (sg.getSequences(null).contains(s)) + for (int i = 0; i < this.groups.size(); i++) { - return sg; + SequenceGroup sg = groups.get(i); + + if (sg.getSequences(null).contains(s)) + { + return sg; + } } } - return null; } @@ -294,60 +312,59 @@ public class Alignment implements AlignmentI */ public SequenceGroup[] findAllGroups(SequenceI s) { - Vector temp = new Vector(); + ArrayList temp = new ArrayList(); - int gSize = groups.size(); - for (int i = 0; i < gSize; i++) + synchronized (groups) { - SequenceGroup sg = (SequenceGroup) groups.elementAt(i); - if (sg == null || sg.getSequences(null) == null) + int gSize = groups.size(); + for (int i = 0; i < gSize; i++) { - this.deleteGroup(sg); - gSize--; - continue; - } + SequenceGroup sg = groups.get(i); + if (sg == null || sg.getSequences(null) == null) + { + this.deleteGroup(sg); + gSize--; + continue; + } - if (sg.getSequences(null).contains(s)) - { - temp.addElement(sg); + if (sg.getSequences(null).contains(s)) + { + temp.add(sg); + } } } - SequenceGroup[] ret = new SequenceGroup[temp.size()]; - - for (int i = 0; i < temp.size(); i++) - { - ret[i] = (SequenceGroup) temp.elementAt(i); - } - - return ret; + return temp.toArray(ret); } /** */ public void addGroup(SequenceGroup sg) { - if (!groups.contains(sg)) + synchronized (groups) { - if (hiddenSequences.getSize() > 0) + if (!groups.contains(sg)) { - int i, iSize = sg.getSize(); - for (i = 0; i < iSize; i++) + if (hiddenSequences.getSize() > 0) { - if (!sequences.contains(sg.getSequenceAt(i))) + int i, iSize = sg.getSize(); + for (i = 0; i < iSize; i++) { - sg.deleteSequence(sg.getSequenceAt(i), false); - iSize--; - i--; + if (!sequences.contains(sg.getSequenceAt(i))) + { + sg.deleteSequence(sg.getSequenceAt(i), false); + iSize--; + i--; + } } - } - if (sg.getSize() < 1) - { - return; + if (sg.getSize() < 1) + { + return; + } } - } - groups.addElement(sg); + groups.add(sg); + } } } @@ -413,20 +430,26 @@ public class Alignment implements AlignmentI public void deleteAllGroups() { - if (annotations != null) + synchronized (groups) { - removeAnnotationForGroup(null); + if (annotations != null) + { + removeAnnotationForGroup(null); + } + groups.clear(); } - groups.removeAllElements(); } /** */ public void deleteGroup(SequenceGroup g) { - if (groups.contains(g)) + synchronized (groups) { - removeAnnotationForGroup(g); - groups.removeElement(g); + if (groups.contains(g)) + { + removeAnnotationForGroup(g); + groups.remove(g); + } } } @@ -598,12 +621,13 @@ public class Alignment implements AlignmentI public void setGapCharacter(char gc) { gapCharacter = gc; - - for (int i = 0; i < sequences.size(); i++) + synchronized (sequences) { - Sequence seq = (Sequence) sequences.elementAt(i); - seq.setSequence(seq.getSequenceAsString().replace('.', gc) - .replace('-', gc).replace(' ', gc)); + for (SequenceI seq : sequences) + { + seq.setSequence(seq.getSequenceAsString().replace('.', gc) + .replace('-', gc).replace(' ', gc)); + } } } @@ -1054,16 +1078,21 @@ public class Alignment implements AlignmentI public CigarArray getCompactAlignment() { - SeqCigar alseqs[] = new SeqCigar[sequences.size()]; - for (int i = 0; i < sequences.size(); i++) + synchronized (sequences) { - alseqs[i] = new SeqCigar((SequenceI) sequences.elementAt(i)); + SeqCigar alseqs[] = new SeqCigar[sequences.size()]; + int i = 0; + for (SequenceI seq : sequences) + { + alseqs[i++] = new SeqCigar(seq); + } + CigarArray cal = new CigarArray(alseqs); + cal.addOperation(CigarArray.M, getWidth()); + return cal; } - CigarArray cal = new CigarArray(alseqs); - cal.addOperation(CigarArray.M, getWidth()); - return cal; } + @Override public void setProperty(Object key, Object value) { if (alignmentProperties == null) @@ -1187,6 +1216,10 @@ public class Alignment implements AlignmentI public void append(AlignmentI toappend) { + if (toappend == this) + { + System.err.println("Self append may cause a deadlock."); + } // TODO test this method for a future 2.5 release // currently tested for use in jalview.gui.SequenceFetcher boolean samegap = toappend.getGapCharacter() == getGapCharacter(); @@ -1194,26 +1227,27 @@ public class Alignment implements AlignmentI boolean hashidden = toappend.getHiddenSequences() != null && toappend.getHiddenSequences().hiddenSequences != null; // get all sequences including any hidden ones - Vector sqs = (hashidden) ? toappend.getHiddenSequences() + List sqs = (hashidden) ? toappend.getHiddenSequences() .getFullAlignment().getSequences() : toappend.getSequences(); if (sqs != null) { - Enumeration sq = sqs.elements(); - while (sq.hasMoreElements()) + synchronized (sqs) { - SequenceI addedsq = (SequenceI) sq.nextElement(); - if (!samegap) + for (SequenceI addedsq : sqs) { - char[] oldseq = addedsq.getSequence(); - for (int c = 0; c < oldseq.length; c++) + if (!samegap) { - if (oldseq[c] == oldc) + char[] oldseq = addedsq.getSequence(); + for (int c = 0; c < oldseq.length; c++) { - oldseq[c] = gapCharacter; + if (oldseq[c] == oldc) + { + oldseq[c] = gapCharacter; + } } } + addSequence(addedsq); } - addSequence(addedsq); } } AlignmentAnnotation[] alan = toappend.getAlignmentAnnotation(); diff --git a/src/jalview/datamodel/AlignmentI.java b/src/jalview/datamodel/AlignmentI.java index 71467f7..1f6390e 100755 --- a/src/jalview/datamodel/AlignmentI.java +++ b/src/jalview/datamodel/AlignmentI.java @@ -56,11 +56,12 @@ public interface AlignmentI extends AnnotatedCollectionI public boolean isAligned(boolean includeHidden); /** - * Gets sequences as a Vector - * + * Gets sequences as a Synchronized collection + * * @return All sequences in alignment. */ - public Vector getSequences(); + @Override + public List getSequences(); /** * Gets sequences as a SequenceI[] diff --git a/src/jalview/datamodel/HiddenSequences.java b/src/jalview/datamodel/HiddenSequences.java index 7914d3d..e9f6d1f 100755 --- a/src/jalview/datamodel/HiddenSequences.java +++ b/src/jalview/datamodel/HiddenSequences.java @@ -175,25 +175,29 @@ public class HiddenSequences end = hiddenSequences.length - 1; } - for (int index = end; index > start; index--) + List asequences; + synchronized (asequences = alignment.getSequences()) { - SequenceI seq = hiddenSequences[index]; - hiddenSequences[index] = null; - - if (seq != null) + for (int index = end; index > start; index--) { - if (seq.getLength() > 0) - { - revealedSeqs.addElement(seq); - alignment.getSequences().insertElementAt(seq, alignmentIndex); - } - else + SequenceI seq = hiddenSequences[index]; + hiddenSequences[index] = null; + + if (seq != null) { - System.out.println(seq.getName() - + " has been deleted whilst hidden"); + if (seq.getLength() > 0) + { + revealedSeqs.addElement(seq); + asequences.add(alignmentIndex, seq); + } + else + { + System.out.println(seq.getName() + + " has been deleted whilst hidden"); + } } - } + } } return revealedSeqs; diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 3a0e3f5..f597a60 100755 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -3707,10 +3707,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, // almost certainly a quicker way to do this - but we keep it simple Hashtable scoreSorts = new Hashtable(); AlignmentAnnotation aann[]; - Enumeration sq = viewport.getAlignment().getSequences().elements(); - while (sq.hasMoreElements()) + for (SequenceI sqa:viewport.getAlignment().getSequences()) { - aann = ((SequenceI) sq.nextElement()).getAnnotation(); + aann = sqa.getAnnotation(); for (int i = 0; aann != null && i < aann.length; i++) { if (aann[i].hasScore() && aann[i].sequenceRef != null) diff --git a/src/jalview/gui/PaintRefresher.java b/src/jalview/gui/PaintRefresher.java index 9dc7f32..219fbf8 100755 --- a/src/jalview/gui/PaintRefresher.java +++ b/src/jalview/gui/PaintRefresher.java @@ -18,6 +18,7 @@ package jalview.gui; import java.util.*; +import java.util.List; import java.awt.*; @@ -179,7 +180,16 @@ public class PaintRefresher { if (i < comp.getHeight()) { - comp.getSequences().insertElementAt(a1[i], i); + // TODO: the following does not trigger any recalculation of height/etc, or maintain the dataset + if (comp.getDataset()!=source.getDataset()) + { + // raise an implementation warning here - not sure if this situation will ever occur + System.err.println("IMPLEMENTATION PROBLEM: DATASET out of sync due to an insert whilst calling PaintRefresher.validateSequences(AlignmentI, ALignmentI)"); + } + List alsq; + synchronized (alsq=comp.getSequences()) { + alsq.add(i, a1[i]); + } } else { diff --git a/src/jalview/gui/SequenceFetcher.java b/src/jalview/gui/SequenceFetcher.java index df955dd..e43f82c 100755 --- a/src/jalview/gui/SequenceFetcher.java +++ b/src/jalview/gui/SequenceFetcher.java @@ -753,19 +753,21 @@ public class SequenceFetcher extends JPanel implements Runnable title = getDefaultRetrievalTitle(); } SequenceFeature[] sfs = null; - for (Enumeration sq = al.getSequences().elements(); sq - .hasMoreElements();) + List alsqs; + synchronized (alsqs = al.getSequences()) { - if ((sfs = ((SequenceI) sq.nextElement()).getDatasetSequence() - .getSequenceFeatures()) != null) + for (SequenceI sq : alsqs) { - if (sfs.length > 0) + if ((sfs = (sq).getDatasetSequence().getSequenceFeatures()) != null) { - af.setShowSeqFeatures(true); - break; + if (sfs.length > 0) + { + af.setShowSeqFeatures(true); + break; + } } - } + } } Desktop.addInternalFrame(af, title, AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT); diff --git a/src/jalview/io/VamsasAppDatastore.java b/src/jalview/io/VamsasAppDatastore.java index fb6465c..93460e3 100644 --- a/src/jalview/io/VamsasAppDatastore.java +++ b/src/jalview/io/VamsasAppDatastore.java @@ -42,6 +42,7 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.Iterator; +import java.util.List; import java.util.Vector; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; @@ -546,12 +547,7 @@ public class VamsasAppDatastore else { // first find the alignment sequence to associate this with. - SequenceI jvalsq = null; - Enumeration jval = av.getAlignment().getSequences() - .elements(); - while (jval.hasMoreElements()) - { - jvalsq = (SequenceI) jval.nextElement(); + for (SequenceI jvalsq:av.getAlignment().getSequences()) { // saveDatasetSequenceAnnotation(AlSeqMaps,(uk.ac.vamsas.objects.core.Sequence) // sref, aa[i]); if (jvalsq.getDatasetSequence() == aa[i].sequenceRef) @@ -884,7 +880,7 @@ public class VamsasAppDatastore * creates/syncs the jvalsq from the alignment sequence */ private boolean syncFromAlignmentSequence(AlignmentSequence valseq, - char valGapchar, char gapChar, Vector dsseqs) + char valGapchar, char gapChar, List dsseqs) { boolean modal = false; @@ -1573,7 +1569,7 @@ public class VamsasAppDatastore // ///LOAD DATASET DataSet dataset = root.getDataSet(_ds); int i, iSize = dataset.getSequenceCount(); - Vector dsseqs; + List dsseqs; jalview.datamodel.Alignment jdataset = (jalview.datamodel.Alignment) getvObj2jv(dataset); int jremain = 0; if (jdataset == null) @@ -1620,8 +1616,8 @@ public class VamsasAppDatastore SequenceI[] seqs = new SequenceI[dsseqs.size()]; for (i = 0, iSize = dsseqs.size(); i < iSize; i++) { - seqs[i] = (SequenceI) dsseqs.elementAt(i); - dsseqs.setElementAt(null, i); + seqs[i] = dsseqs.get(i); + dsseqs.set(i, null); } jdataset = new jalview.datamodel.Alignment(seqs); Cache.log.debug("New vamsas dataset imported into jalview."); @@ -1782,8 +1778,8 @@ public class VamsasAppDatastore SequenceI[] seqs = new SequenceI[dsseqs.size()]; for (i = 0, iSize = dsseqs.size(); i < iSize; i++) { - seqs[i] = (SequenceI) dsseqs.elementAt(i); - dsseqs.setElementAt(null, i); + seqs[i] = dsseqs.get(i); + dsseqs.set(i,null); } jal = new jalview.datamodel.Alignment(seqs); Cache.log.debug("New vamsas alignment imported into jalview " diff --git a/src/jalview/io/vamsas/Tree.java b/src/jalview/io/vamsas/Tree.java index 5fdd0c9..ae53074 100644 --- a/src/jalview/io/vamsas/Tree.java +++ b/src/jalview/io/vamsas/Tree.java @@ -20,6 +20,7 @@ package jalview.io.vamsas; import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; +import java.util.List; import java.util.Vector; import jalview.analysis.NJTree; @@ -264,10 +265,10 @@ public class Tree extends DatastoreItem SeqCigar[] tseqs = new SeqCigar[sequences.length]; System.arraycopy(sequences, 0, tseqs, 0, sequences.length); Vector alsq = new Vector(); - Enumeration as = jal.getSequences().elements(); - while (as.hasMoreElements()) + List jalsqs; + synchronized (jalsqs=jal.getSequences()) + {for (SequenceI asq:jalsqs) { - SequenceI asq = (SequenceI) as.nextElement(); for (int t = 0; t < sequences.length; t++) { if (tseqs[t] != null -- 1.7.10.2