Package sim.engine

Class ParallelSequence

java.lang.Object
sim.engine.Sequence
sim.engine.ParallelSequence
All Implemented Interfaces:
Serializable, Steppable

public class ParallelSequence extends Sequence
Spawns all the sequence elements in parallel on separate threads. This should ONLY be used if you know that all of the elements in the sequence can be executed independently of one another without any race conditions. No synchronization on the model data is done -- you're responsible for that if you need it.

For example, keep in mind that the random number generator is unsynchronized. If you access the random number generator from within a ParallelSequence, or indeed from multiple threads you've spawned in other situations, you need to remember to lock on the random number generator itself.

In the same vein, if you use a RandomSequence within a ParallelSequence, you need to let the RandomSequence know this so that it will lock on the random number generator properly. This is done by setting the shouldSynchronize flag in the RandomSequence.

ParallelSequences are lightweight: they reuse the same threads if stepped repeatedly. This means that you must never attach a ParallelSequence inside itself -- that'd be an infinite loop, but it also would create weird thread errors.

While ParallelSequences might LOOK cool, generally speaking the only time you should ever think to use them is if you actually HAVE multiple CPUs on your computer. Otherwise they're almost certainly not the solution to your odd multiple-thread needs.

Important Note Because ParallelSequences are lightweight, their threads are persistent, even after your step() method has completed (this allows them to be reused for the next step() method. If the ParallelSequence is garbage collected, we automatically delete all its threads in its finalize() method. And that's the rub: even if you get rid of your ParallelSequence, it's often the case that its garbage collection is delayed, or even that the VM will never garbage collect it.

Thus when you're done with your ParallelSequence and wish to throw it away, you should always call cleanup(), which deletes the threads manually. Otherwise the thread resources will leak and quickly consume all your available memory.

Alternatively you can call setDestroysThreads(true) on your ParallelSequence. This will cause the ParallelSequence to destroy its threads every single time the ParallelSequence's step() method completes. This is expensive but you don't have to keep track of the ParallelSequence at the end of the run to call cleanup() on it. It's not a bad idea for a ParallelSequence which is one-shot rather than repeating.

Be sure to read the class documentation on sim.engine.Sequence

See Also:
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    Indicates that MASON should determine how many threads to use based on the number of CPUs.
    static final int
     

    Fields inherited from class sim.engine.Sequence

    size, steps
  • Constructor Summary

    Constructors
    Constructor
    Description
    Creates an immutable ParallelSequence with one thread per steppable in the collection.
    ParallelSequence(Collection steps, int threads)
    Creates an immutable ParallelSequence with the specified number of threads, or if threads==ParallelSequence.CPUS, then the number of threads is determined at runtime based on the number of CPUs or cores on the system, or if threads == ParallelSequence.STEPPABLES, then the number of threads is the size of the collection passed in (and may change as the collection grows or shrinks).
    Creates an immutable ParallelSequence with one thread per steppable.
    ParallelSequence(Steppable[] steps, int threads)
    Creates an immutable ParallelSequence with the specified number of threads, or if threads==ParallelSequence.CPUS, then the number of threads is determined at runtime based on the number of CPUs or cores on the system, or if threads == ParallelSequence.STEPPABLES, then the number of threads is the size of the steps array passed in.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Requests that the provided Steppable be added to the Sequence prior to the next step() call.
    void
    Requests that the provided Steppables be added to the Sequence prior to the next step() call.
    void
    addSteppables(Steppable[] steppables)
    Requests that the provided Steppables be added to the Sequence prior to the next step() call.
    protected boolean
    If your subclass does not respect order, override this method to return false, and Sequence will ignore the ensuresOrder result.
    void
    Call this just before you get rid of a ParallelSequence: for example, one good place is the stop() method of your simulation.
     
    boolean
     
    boolean
    Returns whether the order among the remaining Steppables in the internal array is maintained after removing Steppables via removeSteppable() or removeSteppables().
    boolean
    Returns whether the Sequence uses a Set internally to manage the internal array.
    void
    Requests that the provided Steppable be removed from the Sequence prior to the next step() call.
    void
    Requests that the provided Steppables be removed from the Sequence prior to the next step() call.
    void
    Requests that the provided Steppables be removed from the Sequence prior to the next step() call.
    void
    Requests that the provided Steppables replace the existing Steppables in the internal array prior to the next step() call.
    void
    Requests that the provided Steppables replace the existing Steppables in the internal array prior to the next step() call.
    void
    setDestroysThreads(boolean val)
     
    void
    setEnsuresOrder(boolean val)
    Sets whether the order among the remaining Steppables in the internal array is maintained after removing Steppables via removeSteppable() or removeSteppables().
    void
    setUsesSets(boolean val)
    Sets whether the Sequence uses a Set internally to manage the internal array.
    void
    step(SimState state)
     

    Methods inherited from class sim.engine.Sequence

    loadSteps

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • CPUS

      public static final int CPUS
      Indicates that MASON should determine how many threads to use based on the number of CPUs.
      See Also:
    • STEPPABLES

      public static final int STEPPABLES
      See Also:
  • Constructor Details

    • ParallelSequence

      public ParallelSequence(Steppable[] steps, int threads)
      Creates an immutable ParallelSequence with the specified number of threads, or if threads==ParallelSequence.CPUS, then the number of threads is determined at runtime based on the number of CPUs or cores on the system, or if threads == ParallelSequence.STEPPABLES, then the number of threads is the size of the steps array passed in.
    • ParallelSequence

      public ParallelSequence(Steppable[] steps)
      Creates an immutable ParallelSequence with one thread per steppable.
    • ParallelSequence

      public ParallelSequence(Collection steps, int threads)
      Creates an immutable ParallelSequence with the specified number of threads, or if threads==ParallelSequence.CPUS, then the number of threads is determined at runtime based on the number of CPUs or cores on the system, or if threads == ParallelSequence.STEPPABLES, then the number of threads is the size of the collection passed in (and may change as the collection grows or shrinks).
    • ParallelSequence

      public ParallelSequence(Collection steps)
      Creates an immutable ParallelSequence with one thread per steppable in the collection.
  • Method Details

    • getDestroysThreads

      public boolean getDestroysThreads()
    • setDestroysThreads

      public void setDestroysThreads(boolean val)
    • getCleaner

      public Steppable getCleaner()
    • cleanup

      public void cleanup()
      Call this just before you get rid of a ParallelSequence: for example, one good place is the stop() method of your simulation. Never call this method inside the ParallelSequence's own step() method. This method deletes the threads so the ParallelSequence is ready to be thrown away. We also do this in finalize() but finalize() is not guaranteed to be called at any particular time, which can result in unexpected memory leaks. Think of this method as the same kind of thing as a Graphics or Window's dispose() method.
    • canEnsureOrder

      protected boolean canEnsureOrder()
      Description copied from class: Sequence
      If your subclass does not respect order, override this method to return false, and Sequence will ignore the ensuresOrder result.
      Overrides:
      canEnsureOrder in class Sequence
    • step

      public void step(SimState state)
      Specified by:
      step in interface Steppable
      Overrides:
      step in class Sequence
    • replaceSteppables

      public void replaceSteppables(Collection collection)
      Description copied from class: Sequence
      Requests that the provided Steppables replace the existing Steppables in the internal array prior to the next step() call.
      Overrides:
      replaceSteppables in class Sequence
    • replaceSteppables

      public void replaceSteppables(Steppable[] steppables)
      Description copied from class: Sequence
      Requests that the provided Steppables replace the existing Steppables in the internal array prior to the next step() call.
      Overrides:
      replaceSteppables in class Sequence
    • addSteppable

      public void addSteppable(Steppable steppable)
      Description copied from class: Sequence
      Requests that the provided Steppable be added to the Sequence prior to the next step() call.
      Overrides:
      addSteppable in class Sequence
    • addSteppables

      public void addSteppables(Steppable[] steppables)
      Description copied from class: Sequence
      Requests that the provided Steppables be added to the Sequence prior to the next step() call.
      Overrides:
      addSteppables in class Sequence
    • addSteppables

      public void addSteppables(Collection steppables)
      Description copied from class: Sequence
      Requests that the provided Steppables be added to the Sequence prior to the next step() call.
      Overrides:
      addSteppables in class Sequence
    • removeSteppable

      public void removeSteppable(Steppable steppable)
      Description copied from class: Sequence
      Requests that the provided Steppable be removed from the Sequence prior to the next step() call.
      Overrides:
      removeSteppable in class Sequence
    • removeSteppables

      public void removeSteppables(Steppable[] steppables)
      Description copied from class: Sequence
      Requests that the provided Steppables be removed from the Sequence prior to the next step() call.
      Overrides:
      removeSteppables in class Sequence
    • removeSteppables

      public void removeSteppables(Collection steppables)
      Description copied from class: Sequence
      Requests that the provided Steppables be removed from the Sequence prior to the next step() call.
      Overrides:
      removeSteppables in class Sequence
    • getEnsuresOrder

      public boolean getEnsuresOrder()
      Description copied from class: Sequence
      Returns whether the order among the remaining Steppables in the internal array is maintained after removing Steppables via removeSteppable() or removeSteppables(). Note that this value may be entirely ignored by subclasses for which maintaining order doesn't make sense (such as parallel or random sequences). Also if you use sets (via setUsesSets(true)), then order is never ensured regardless.
      Overrides:
      getEnsuresOrder in class Sequence
    • setEnsuresOrder

      public void setEnsuresOrder(boolean val)
      Description copied from class: Sequence
      Sets whether the order among the remaining Steppables in the internal array is maintained after removing Steppables via removeSteppable() or removeSteppables(). Note that this value may be entirely ignored by subclasses for which maintaining order doesn't make sense (such as parallel or random sequences). Also if you use sets (via setUsesSets(true)), then order is never ensured regardless.
      Overrides:
      setEnsuresOrder in class Sequence
    • getUsesSets

      public boolean getUsesSets()
      Description copied from class: Sequence
      Returns whether the Sequence uses a Set internally to manage the internal array. This is faster, often much faster, for large numbers of removals (perhaps more than 5 or so), but requires that each Steppable in the internal array be unique.
      Overrides:
      getUsesSets in class Sequence
    • setUsesSets

      public void setUsesSets(boolean val)
      Description copied from class: Sequence
      Sets whether the Sequence uses a Set internally to manage the internal array. This is faster, often much faster, for large numbers of removals (perhaps more than 5 or so), but requires that each Steppable in the internal array be unique.
      Overrides:
      setUsesSets in class Sequence