Package ec.util

Class ThreadPool

java.lang.Object
ec.util.ThreadPool
All Implemented Interfaces:
Serializable

public class ThreadPool extends Object implements Serializable
ThreadPool.java A simple, lightweight thread pool, for those who cannot or will not use Java's baroque java.util.concurrent package.

A ThreadPool manages a set of "Workers", each of which manages a java.lang.Thread ready to be used to run a task for you. The threads are setDaemon(true), so they'll automatically die when the program is terminated. At any point in time, a Worker is either *pooled*, meaning it is in the ThreadPool and available to be used, or it is *outstanding*, meaning that it is presently working on a Runnable that has been assigned it.

You obtain a Worker from a ThreadPool by calling start(...), passing in a Runnable which is the code you wish the Worker to perform. When this Runnable is completed, that is, when its run() method exits, the Worker will automatically rejoin the ThreadPool and become available for use in future.

A Worker manages a Thread underneath in which the Runnable is run. The Worker has a method called interrupt() which you can call if you wish to have interrupt() called on the underlying Thread; otherwise you shouldn't really play around with the underlying thread even if you can obtain it (via Thread.currentThread() for example).

If there are no Workers presently available in the pool when you request one, a new Worker, and an associated underlying thread, will be created on the fly. When this Worker is done, it will enter the Pool with the others. Thus the total number of Workers will never shrink, though it may stay the same size. If you want to trim the number of Workers presently in the Pool, you can call killPooled(), though it's not a common need.

You might wish to control the total number of workers at any particular time. You can do this by using a version of start() which takes a maximum number of workers. This version will block as long as the number of current working threads is greater than or equal to the desired maximum, then start() afterwards.

You can wait for an outstanding Worker to finish its task by calling join(...). You can wait for all outstanding Workers to finish their tasks by calling joinAll(...). This is useful for spawning a number of Workers, then waiting for them to all finish. And you can wait for all outstanding Workers to finish their tasks, followed by killing them and all their underlying threads (perhaps to clean up in preparation for quitting your program) by calling killAll(...).

ThreadPool is java.io.Serializable: but if it is serialized out, it won't serialize out its worker threads, so when it is deserialized back in, the threads will be gone.

See Also:
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static interface 
    A Worker is a special kind of object which represents an underlying Worker thread usable in the ThreadPool.
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    int
    Returns the total number of outstanding workers (those working on something right now).
    int
    Returns the total number of pooled workers (those not working on something right now).
    int
    Returns the total number of workers, both pooled and outstanding (working on something).
    boolean
    If the thread is presently running a Runnable of any kind, blocks until the Runnable has finished running.
    boolean
    Joins the given thread running the given Runnable.
    void
    Waits until there are no outstanding workers: all pool workers are in the pool.
    void
    Waits until there are no outstanding workers: all pool workers are in the pool.
    void
    Kills all unused workers in the pool.
    static void
    main(String[] args)
     
    Start a thread on the given Runnable and returns it.
    start(Runnable run, int maximumOutstandingWorkers)
    Start a thread on the given Runnable and returns it.
    start(Runnable run, int maximumOutstandingWorkers, String name)
    Start a thread on the given Runnable with a given thread name (for debugging purposes) and returns it.
    start(Runnable run, String name)
    Start a thread on the given Runnable with a given thread name (for debugging purposes).

    Methods inherited from class java.lang.Object

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

    • ThreadPool

      public ThreadPool()
  • Method Details

    • start

      public ThreadPool.Worker start(Runnable run)
      Start a thread on the given Runnable and returns it.
    • start

      public ThreadPool.Worker start(Runnable run, String name)
      Start a thread on the given Runnable with a given thread name (for debugging purposes).
    • start

      public ThreadPool.Worker start(Runnable run, int maximumOutstandingWorkers)
      Start a thread on the given Runnable and returns it. This method blocks and does not start the thread as long as doing so would cause the number of outstanding workers to exceed the provided maximum number. This method can be used to limit the number of jobs processed by the ThreadPool at any one time.
    • start

      public ThreadPool.Worker start(Runnable run, int maximumOutstandingWorkers, String name)
      Start a thread on the given Runnable with a given thread name (for debugging purposes) and returns it. This method blocks and does not start the thread as long as doing so would cause the number of outstanding workers to exceed the provided maximum number. This method can be used to limit the number of jobs processed by the ThreadPool at any one time.
    • getTotalWorkers

      public int getTotalWorkers()
      Returns the total number of workers, both pooled and outstanding (working on something).
    • getPooledWorkers

      public int getPooledWorkers()
      Returns the total number of pooled workers (those not working on something right now).
    • getOutstandingWorkers

      public int getOutstandingWorkers()
      Returns the total number of outstanding workers (those working on something right now).
    • join

      public boolean join(ThreadPool.Worker thread, Runnable run)
      Joins the given thread running the given Runnable. If the thread is not presently running this Runnable, then the method immediately returns. Else it blocks until the Runnable has terminated. Returns true if the worker was working on the provided Runnable, else false.
    • join

      public boolean join(ThreadPool.Worker thread)
      If the thread is presently running a Runnable of any kind, blocks until the Runnable has finished running. Else returns immediately. Returns true if the worker was working on some Runnable, else false.
    • joinAll

      public void joinAll()
      Waits until there are no outstanding workers: all pool workers are in the pool.
    • killPooled

      public void killPooled()
      Kills all unused workers in the pool. This can be used to reduce the pool to a manageable size if the number of workers in it has grown too large (an unlikely scenario). You can still use the ThreadPool after calling this function; but it will have to build new workers.
    • killAll

      public void killAll()
      Waits until there are no outstanding workers: all pool workers are in the pool. Then kills all the workers. This is the approprate way to shut down the ThreadPool in preparation for quitting your program. You can still use the ThreadPool after calling this function; but it will have to build new workers.
    • main

      public static void main(String[] args)