Thread Cache : Thread Pool « Threads « Java

Home
Java
1.2D Graphics GUI
2.3D
3.Advanced Graphics
4.Ant
5.Apache Common
6.Chart
7.Class
8.Collections Data Structure
9.Data Type
10.Database SQL JDBC
11.Design Pattern
12.Development Class
13.EJB3
14.Email
15.Event
16.File Input Output
17.Game
18.Generics
19.GWT
20.Hibernate
21.I18N
22.J2EE
23.J2ME
24.JDK 6
25.JNDI LDAP
26.JPA
27.JSP
28.JSTL
29.Language Basics
30.Network Protocol
31.PDF RTF
32.Reflection
33.Regular Expressions
34.Scripting
35.Security
36.Servlets
37.Spring
38.Swing Components
39.Swing JFC
40.SWT JFace Eclipse
41.Threads
42.Tiny Application
43.Velocity
44.Web Services SOA
45.XML
Java » Threads » Thread PoolScreenshots 
Thread Cache
   
// ThreadCache.java
// $Id: ThreadCache.java,v 1.16 2000/08/16 21:37:58 ylafon Exp $
// (c) COPYRIGHT MIT and INRIA, 1996-1997.
// Please first read the full copyright statement in file COPYRIGHT.html


class CachedThread extends Thread {
    Runnable     runner     = null;
    boolean      alive      = true;
    ThreadCache  cache      = null;
    CachedThread next       = null;
    CachedThread prev       = null;
    boolean      terminated = false;
    boolean      started    = false;
    boolean      firstime   = true;

    synchronized boolean isTerminated() {
  boolean ret = terminated;
  terminated = true;
  return ret;
    }

    synchronized Runnable waitForRunner() {
  boolean to = false;

  while alive ) {
      // Is a runner available ?
      if runner != null ) {
    Runnable torun = runner;
    firstime = false;
    runner   = null;
    return torun;
      else if firstime ) {
    // This thread will not be declared free until it runs once:
    try {
        wait();
    catch (InterruptedException ex) {
    }
      else if alive = cache.isFree(this, to) ) {
    // Notify the cache that we are free, and continue if allowed:
    try {
        int idleto = cache.getIdleTimeout();
        to = false;
        if idleto > ) {
      wait(idleto);
      to = (runner == null);
        else {
      wait();
        }
    catch (InterruptedException ex) {
    }
      }
  }
  return null;
    }

    synchronized void kill() {
  alive = false;
  notify();
    }

    synchronized boolean wakeup(Runnable runnable) {
  if alive ) {
      runner = runnable;
      if ! started 
    this.start();
      notify();
      return true;
  else {
      return false;
  }
    }

    public synchronized void start() {
  super.start();
  this.started = true;
    }

    public void run() {
  try {
      while true ) {
    // Wait for a runner:
    Runnable torun = waitForRunner();
    // If runner, run:
    if torun != null 
        torun.run();
    // If dead, stop
    if ! alive )
        break;
      }
  finally {
      cache.isDead(this);
  }
    }

    CachedThread(ThreadCache cache, int id) {
  super(cache.getThreadGroup(), cache.getThreadGroup().getName()+":"+id);
  this.cache = cache;
  setPriority(cache.getThreadPriority());
  setDaemon(true);
    }

}

public class ThreadCache {
    private static final boolean debug = false;

    /**
     * Default number of cached threads.
     */
    private static final int DEFAULT_CACHESIZE = 5;
    /**
     * Has this thread cache been initialized ?
     */
    protected boolean inited = false;
    /**
     * The thread group for this thread cache.
     */
    protected ThreadGroup group = null;
    /**
     * Number of cached threads.
     */
    protected int cachesize = DEFAULT_CACHESIZE;
    /**
     * Number of created threads.
     */
    protected int threadcount = 0;
    /**
     * Uniq thread identifier within this ThreadCache instance.
     */
    protected int threadid = 0;
    /**
     * Number of idle threads to always maintain alive.
     */
    protected int idlethreads = 0;
    /**
     * Should we queue thread requests, rather then creating new threads.
     */
    protected boolean growasneeded = false;
    /**
     * Number of used threads
     */
    protected int usedthreads = 0;
    /**
     * List of free threads.
     */
    protected CachedThread freelist = null;
    protected CachedThread freetail = null;
    /**
     * The idle timeout, for a thread to wait before being killed.
     * Defaults to <strong>5000</strong> milliseconds.
     */
    protected int idletimeout = 5000;
    /**
     * Cached thread priority.
     */
    protected int threadpriority = 5;

    /**
     * Get the idle timeout value for this cache.
     @return The idletimeout value, or negative if no timeout applies.
     */

    synchronized final int getIdleTimeout() {
  return (threadcount <= idlethreads? -: idletimeout;
    }

    /**
     * The given thread is about to be declared free.
     @return A boolean, <strong>true</strong> if the thread is to continue
     * running, <strong>false</strong> if the thread should stop.
     */

    final synchronized boolean isFree(CachedThread t, boolean timedout) {
  if timedout && (threadcount > idlethreads) ) {
      if ! t.isTerminated() ) {
    threadcount--;
    usedthreads--;
    notifyAll();
      
      return false;
  else if threadcount <= cachesize ) {
      t.prev   = freetail;
      if (freetail != null)
    freetail.next = t;
      freetail = t;
      if (freelist == null)
    freelist = t;
      usedthreads--;
      notifyAll();
      return true;
  else {
      if ! t.isTerminated() ) {
    threadcount--;
    usedthreads--;
    notifyAll();
      }
      return false;
  }
    }

    /**
     * The given thread has terminated, cleanup any associated state.
     @param dead The dead CachedThread instance.
     */

    final synchronized void isDead(CachedThread t) {
  if debug )
      System.out.println("** "+t+": is dead tc="+threadcount);
  if ! t.isTerminated() ) {
      threadcount--;
      notifyAll();
  }
    }

    /**
     * Create a new thread within this thread cache.
     @return A new CachedThread instance.
     */

    private synchronized CachedThread createThread() {
  threadcount++;
  threadid++;
  return new CachedThread(this, threadid);
    }

    /**
     * Allocate a new thread, as requested.
     @param waitp Should we wait until a thread is available ?
     @return A launched CachedThread instance, or <strong>null</strong> if 
     * unable to allocate a new thread, and <code>waitp</code> is <strong>
     * false</strong>.
     */

    protected synchronized CachedThread allocateThread(boolean waitp) {
  CachedThread t = null;
  while true ) {
      if freelist != null ) {
    if debug )
        System.out.println("*** allocateThread: free thread");
    t        = freelist;
    freelist = freelist.next;
    if (freelist != null) {
        freelist.prev = null;
    else {
        freetail = null;
    }
    t.next = null;
    break;
      else if ((threadcount < cachesize|| growasneeded) {
    if debug )
        System.out.println("*** create new thread.");
    t = createThread();
    break;
      else if waitp ) {
    if debug )
        System.out.println("*** wait for a thread.");
    // Wait for a thread to become available
    try {
        wait();
    catch (InterruptedException ex) {
    }
      else {
    return null;
      }
  }
  return t;
    }

    /**
     * Set the thread cache size.
     * This will also update the number of idle threads to maintain, if 
     * requested.
     @param cachesize The new thread cache size.
     @param update If <strong>true</strong> also update the number of
     * threads to maintain idle.
     */

    public synchronized void setCachesize(int cachesize, boolean update) {
  this.cachesize = cachesize;
  if update 
      this.idlethreads = (cachesize>>1);
    }

    /**
     * Set the thread cache size.
     * Updaet the number of idle threads to keep alive.
     @param cachesize The new thread cache size.
     */

    public void setCachesize(int cachesize) {
  setCachesize(cachesize, true);
    }

    /**
     * Enable/disable the thread cache to grow as needed.
     * This flag should be turned on only if always getting a thread as fast
     * as possible is critical.
     @param onoff The toggle.
     */

    public void setGrowAsNeeded(boolean onoff) {
  this.growasneeded = onoff;
    }

    /**
     * Set all the cached threads priority.
     * Changing the cached thread priority should be done before the thread
     * cache is initialized, it will <em>not</em> affect already created 
     * threads.
     @param priority The new cachewd threads priority.
     */

    public void setThreadPriority(int priority) {
  threadpriority = priority;
    }

    /**
     * Get the cached thread normal priority.
     @return Currently assigned cached thread priority.
     */

    public int getThreadPriority() {
  return threadpriority;
    }

    /**
     * Set the idle timeout. 
     * The idle timeout value is used to eliminate threads that have remain 
     * idle for too long (although the thread cache will ensure that a 
     * decent minimal number of threads stay around).
     @param idletimeout The new idle timeout.
     */

    public synchronized void setIdleTimeout(int idletimeout) {
  this.idletimeout = idletimeout;
    }

    /**
     * Request a thread to run on the given object.
     @param runnable The object to run with the allocated thread.
     @param waitp If <strong>true</strong> wait until a free thread is 
     * available, otherwise, return <strong>false</strong>.
     @return A boolean, <strong>true</strong> if a thread was successfully
     * allocated for the given object, <strong>false</strong> otherwise.
     */

    public boolean getThread(Runnable runnable, boolean waitp) {
  if debug )
      System.out.println("*** getting a thread for "+runnable);
  if ! inited )
      throw new RuntimeException("Uninitialized thread cache");
  // Allocate and launch the thread:
  while true ) {
      CachedThread t = allocateThread(waitp);
      if t != null ) {
    if t.wakeup(runnable) ) {
        synchronized (this) {
      usedthreads++;
        }
        return true;
    }
      else {
    return false;
      }
  }
    }

    /**
     * Get the ThreadGroup managed by this ThreadCache instance.
     @return A ThreadGroup instance.
     */

    public ThreadGroup getThreadGroup() {
  return group;
    }

    /**
     * Wait until all the threads have finished their duty
     */

    public synchronized void waitForCompletion() {
  while (usedthreads > 0) {
      if debug )
    System.out.println("*** Waiting for "+usedthreads+ " threads");
      try {
    wait();
      catch (InterruptedException ex) {
      }
  }
    }

    /**
     * Initialize the given thread cache.
     * This two stage initialize method is done so that configuration
     * of the thread cache can be done before any thread get actually
     * created.
     */

    public synchronized void initialize() {
  CachedThread t = createThread();
  freelist = t;
  freetail = t;
  t.next = null;
  t.prev = null;
  t.start();
  for (int i = ; i < idlethreads ; i++) {
      t = createThread();
      t.next = freelist;
      t.prev = null;
      freelist.prev = t;
      freelist = t;
      t.start();
  }
  inited = true;
    }

    /**
     * Create a thread cache, whose threads are to be children of the group.
     @param group The thread group to which this thread cache is bound.
     @param nstart Number of thread to create in advance.
     */

    public ThreadCache(ThreadGroup group) {
  this.group = group;
    }

    /**
     * Create a thread cache, after creating a new thread group.
     @param name The name of the thread group to create.
     */

    public ThreadCache(String name) {
  this(new ThreadGroup(name));
    }

    /**
     * Create a thread cache, after creating a new thread group.
     @param parent The parent of the thread group to create.
     @param name The name of the thread group.
     */

    public ThreadCache(ThreadGroup parent, String name) {
  this(new ThreadGroup(parent, name));
    }

}

   
    
    
  
Related examples in the same category
1.Defining a thread for a thread poolDefining a thread for a thread pool
2.Thread pool demo
3.Thread Pools 1
4.Thread Pools 2Thread Pools 2
5.Thread pool
6.Thread Pool 2Thread Pool 2
7.Thread Pool TestThread Pool Test
8.JDK1.5 provides a mechanism to create a pool a scheduled task
9.Very basic implementation of a thread poolVery basic implementation of a thread pool
10.Simple pool of ThreadsSimple pool of Threads
11.Worker thread pool
12.Create a new thread for the thread pool. The create thread will be a daemon thread.
13.Simple thread pool. A task is executed by obtaining a thread from the poolSimple thread pool. A task is executed by obtaining a thread from the pool
14.Simple object pool. Based on ThreadPool and few other classes
15.A utility class that receives a collection of tasks to execute internally and then distributes the tasks among a thread pool.
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.