📄 threadpool.java.org
字号:
package de.spieleck.util;
import java.util.LinkedList;
import java.util.Map;
import java.util.HashMap;
/**
* Implement a thread pool for dispatching arbitrary many jobs
* to a fixed number of workers.
*
* <br /><b>Design Note:</b>Synchronization is done on the internal object
* tasks, since wait()/notify() is used and therefore an external object
* synchronizing on a ThreadPool instance can prevent the ThreadPool from
* working. To avoid this one had to go to notifyAll events.
*
* @author fsn
* @version 0.0
*/
public class ThreadPool
extends ThreadGroup
{
/** The number of worker Threads */
protected int size;
/** The queue of Files which need to be processed */
protected LinkedList tasks;
/** Did we allready have an assignement? */
protected boolean started = false;
/** How much work is left? */
protected int leftWork;
/** How many tasks are still running? */
protected int runningTasks;
/** Do we have special exception handlers? */
protected Map eHandlers;
/** Lock for counting */
protected Object cLock = new Object();
/**
* Construct a pool with a default number of threads.
*/
public ThreadPool()
{
this(5);
}
/**
* Construct a pool with a choosable number of threads.
*/
public ThreadPool(int size)
{
super("ThreadPool");
eHandlers = new HashMap();
tasks = new LinkedList();
this.size = size;
setDaemon(true);
runningTasks = size;
// Of course is is 0, but every starting thread runs into the lock.
leftWork = size;
String nameBase = this.toString()+".";
for(int i = 0; i< size; i++ )
{
Thread th = new WorkerThread(this,nameBase+Integer.toString(i));
th.start();
}
}
/**
* Protected attach a new Exception handler.
*/
public void addExceptionHandler(Class e, ExceptionHandler handler)
{
eHandlers.put(e, handler);
}
/**
* Get the next task to execute
*/
protected Runnable getTask()
{
try
{
synchronized(cLock)
{
runningTasks--;
if ( --leftWork == 0 )
cLock.notify();
}
Runnable r;
synchronized(tasks)
{
tasks.notify();
while ( tasks.isEmpty() )
{
tasks.wait();
}
r = (Runnable) tasks.removeFirst();
}
synchronized(cLock)
{
runningTasks++;
}
return r;
}
catch(InterruptedException e)
{
return null;
}
}
/**
* Add a task to execute
*/
public void addTask(Runnable r)
{
synchronized(tasks)
{
tasks.add(r);
tasks.notify();
}
synchronized(cLock)
{
leftWork++;
if ( !started )
{
started = true;
cLock.notify();
}
}
}
/**
* Wait until we have started doing something.
*/
public void waitStart()
throws InterruptedException
{
synchronized(cLock)
{
while ( !started )
{
cLock.wait();
}
}
}
/**
* Wait until we have started doing something.
*/
public void waitDone()
throws InterruptedException
{
synchronized(cLock)
{
while ( leftWork > 0 )
{
cLock.wait();
}
}
}
/**
* Wait until all jobs are done.
* That is, we have to wait for both, that every single task
* is done and that there are no tasks remaining any more.
* But in the very beginning we assume there is something to do and
* wait for at least one task!
*/
public void join()
{
try
{
waitStart();
waitDone();
}
catch ( InterruptedException e )
{
// cannot cope with this
}
}
/**
* Have we been started ?
*/
public boolean isStarted()
{
synchronized(cLock)
{
return started;
}
}
/**
* How much work do we have left.
*/
public int getLeftWork()
{
synchronized(cLock)
{
return leftWork;
}
}
/**
* How many tasks are still working
*/
public int getRunningTasks()
{
synchronized(cLock)
{
return runningTasks;
}
}
/**
* customizable exception handling.
*/
public void uncaughtException(Thread t, Throwable e)
{
ExceptionHandler eh = (ExceptionHandler) eHandlers.get(e.getClass());
if ( eh != null )
eh.uncaughtException(t, e);
else
super.uncaughtException(t,e);
}
/**
* Do something useful on finalization time
*/
protected void finalize()
throws Throwable
{
interrupt();
destroy();
super.finalize();
}
/**
* A nicer name.
*/
public String toString()
{
return super.toString()+"["+size+"]";
}
/**
* Inner class to actually do something.
*/
protected class WorkerThread
extends Thread
{
public WorkerThread(ThreadGroup tg, String name)
{
super(tg, name);
}
public void run()
{
Runnable task;
while ( true )
{
task = getTask();
if ( task == null )
return;
try
{
task.run();
}
catch(Throwable t)
{
uncaughtException(Thread.currentThread(), t);
}
}
}
}
}
//
// Jacson - Text Filtering with Java.
// Copyright (C) 2002 Frank S. Nestel (nestefan -at- users.sourceforge.net)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -