All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.ginere.base.util.thread.ConsumerPoolThread Maven / Gradle / Ivy

There is a newer version: 1.2.3
Show newest version
/**
 * Copyright: Angel-Ventura Mendo Gomez
 *	      [email protected]
 *
 * $Id: ConsumerPoolThread.java 21 2007-06-23 00:22:03Z ventura $
 */
package eu.ginere.base.util.thread;

import java.util.HashMap;
import java.util.Vector;

import org.apache.log4j.Logger;

/**
 * The same as ConsumerThread but using a pool of threads.
 * 

* Use this pool to distribute work into a pool of thread. Add objects with the function * addObjectect and these objects will be consumed by the threads. The consuming * function must be implemented using the ConsumerThreadInterface. * *

* This Pool has an important point if all threads are busy, stop the caller of the * function addObjectect until one thread is freed, then the caller is awaked. * This do not apply when the calling thread is one of the threads of the pool. * * @author Angel-Ventura Mendo * @version $Revision: 21 $ $Date: 2007-06-23 02:22:03 +0200 $ */ public class ConsumerPoolThread { private static final Logger log = Logger.getLogger(ConsumerPoolThread.class); private static final int DEFAULT_THREAD_POOL_SIZE=5; private final ConsumerThreadInterface consumer; private final Vector threadList=new Vector(); private final HashMap threadMap=new HashMap(); private final Vector objectList=new Vector(); private String threadName; private int threadPoolSize=DEFAULT_THREAD_POOL_SIZE; private boolean stopped=false; private int stopedThreadNumber=0; public ConsumerPoolThread(int threadPoolSize, ConsumerThreadInterface consumer){ this.threadName=getClass().getName(); this.threadPoolSize=threadPoolSize; this.consumer=consumer; initializePool(); } public ConsumerPoolThread(String threadName, int threadPoolSize, ConsumerThreadInterface consumer){ this.threadName=threadName; this.threadPoolSize=threadPoolSize; this.consumer=consumer; initializePool(); } public ConsumerPoolThread(String threadName, ConsumerThreadInterface consumer){ this.threadName=threadName; this.consumer=consumer; initializePool(); } /** * add a new object into the consumer list to be consumed! */ public void addObject(E object){ if(stopped==true){ log.warn("Adding a new object ignored, the pool is stopped"); return ; } // add to the end objectList.add(object); // if (log.isDebugEnabled()){ // log.debug("ADD, size:'"+objectListSize()+"' "+object.hashCode()+" stopped:"+stopedThreadNumber+" "+object.toString()); // } if (stopedThreadNumber==0 && !threadMap.containsKey(Thread.currentThread().getName())){ synchronized (threadList) { try { threadList.wait(); } catch (InterruptedException e) { } } } synchronized (objectList) { objectList.notify(); } } /** * Return the number of thread into the pool size */ public int getThreadPoolSize(){ return threadPoolSize; } public int getRunningThreadNumber(){ return threadPoolSize-stopedThreadNumber; } /** * Numer of inactive thread * @return */ public int getStopedThreadNumber(){ return stopedThreadNumber; } /** * Return the number of objects waiting to be treated */ public int objectListSize(){ return objectList.size(); } public void stopConsumer(){ stopped=true; synchronized (objectList) { objectList.notifyAll(); } // log.debug("Stopping consumer:"+threadName); } private void initializePool(){ if (threadPoolSize<=0){ threadPoolSize=DEFAULT_THREAD_POOL_SIZE; } for (int i=0;ipool; InnerConsumerThread(ConsumerPoolThreadpool,String name,int number){ super(name+"-"+number); this.pool=pool; start(); } public void run(){ while(!stopped){ // Wait untill the list will have some elements synchronized (objectList) { if (objectList.isEmpty()){ // if (log.isDebugEnabled()){ // log.debug("Sleeping "+Thread.currentThread().getName()+" ... "); // } synchronized (threadList) { threadList.notifyAll(); } try { stopedThreadNumber++; objectList.wait(); }catch (InterruptedException e){ }finally{ stopedThreadNumber--; } // log.debug("AWAKE "+Thread.currentThread().getName()+" ... "); } } // gwtting the next element to treat while (!objectList.isEmpty() && !stopped ){ try { E object=null; synchronized (objectList) { if (!objectList.isEmpty()){ object=objectList.remove(0); } } if (object!=null){ // if (log.isDebugEnabled()){ // log.debug("REMOVED, size:'"+objectListSize()+"' "+object.hashCode()+" "+object.toString()); // } try { consumer.consume(pool,object); }catch(Exception e){ log.error("While consumming object!",e); } } }catch(ArrayIndexOutOfBoundsException e){ // may bethe element has been taken by another thread // log.info("While consumming object!",e); } } } // log.info("Consumer stopped:"+getName()); } } /** * Wait the current Thread until the work is done */ public void waitUntilWorkDone(){ while(objectListSize()>0 || getRunningThreadNumber()>0){ if (stopped){ log.fatal("El pool se ha parado de forma anormal. List Size:"+objectListSize()+" running threads:"+getRunningThreadNumber()+"/"+getThreadPoolSize()); return ; } if (log.isDebugEnabled()){ log.debug("List Size:"+objectListSize()+" running threads:"+getRunningThreadNumber()+"/"+getThreadPoolSize()); } try { Thread.sleep(1000); } catch (InterruptedException e) { } } if (log.isInfoEnabled()){ log.info("Work, done. List Size:"+objectListSize()+" running threads:"+getRunningThreadNumber()+"/"+getThreadPoolSize()); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy