package com.xnull.threads ;import java.util.List ;
import java.util.ArrayList ;/**
 * @author Xiongkq
 * @version 1.0
 */
public class SimpleThreadPool
{
  private int maxThreads ;
  private List taskList ;
  private int threadCount ;
  private int freeCount ;
  private boolean shutdown ;  public SimpleThreadPool ()
  {
    this ( 0 , 5 ) ;
  }  public SimpleThreadPool ( int initThreads , int maxThreads )
  {
    taskList = new ArrayList () ;
    this.maxThreads = maxThreads ;
    createWorker ( initThreads ) ;
  }  public synchronized void shutdown ()
  {
    if ( !shutdown )
    {
      shutdown = true ;
      notifyAll () ;
    }
  }  public synchronized void addTask ( Runnable task )
  {
    taskList.add ( task ) ;
    checkWorkers () ;
    notify () ;
  }  private synchronized void gainFreeThead ()
  {
    freeCount++ ;
  }  private synchronized void reduceFreeThead ()
  {
    freeCount-- ;
  }  private void checkWorkers ()
  {
    int allowCreateCount = maxThreads - threadCount ;
    int createCount = taskList.size () - freeCount ;
    if ( createCount > allowCreateCount )
    {
      createCount = allowCreateCount ;
    }    if ( createCount > 0 )
    {
      createWorker ( createCount ) ;
    }
  }  private void createWorker ( int createCount )
  {
    threadCount += createCount ;
    freeCount += createCount ;
    for ( int i = 0 ; i < createCount ; i++ )
    {
      new WorkerThread ().start () ;
    }
  }  private synchronized void notifyThreadDeath ( WorkerThread worker )
  {
    threadCount-- ;
    checkWorkers () ;
  }  private synchronized Runnable getTask ()
  {
    while ( taskList.size () == 0 )
    {
      try
      {
        wait () ;
      }
      catch ( InterruptedException ex )
      {
        return null ;
      }
    }    if ( shutdown )
    {
      return null ;
    }    return ( Runnable ) taskList.get ( 0 ) ;
  }  class WorkerThread
      extends Thread
  {
    public void run ()
    {
      while ( true )
      {
        gainFreeThead () ;
        Runnable run = getTask () ;
        if ( run != null )
        {
          reduceFreeThead () ;
          try
          {
            run.run () ;
          }
          catch ( Throwable ex )
          {
            notifyThreadDeath ( this ) ;
            break ;
          }
        }
        else
        {
          if ( shutdown )
          {
            break ;
          }
        }
      }
    }
  }
}