📄 threadpool.java
字号:
for(int i = 0 ; i < toFree ; i++) {
ControlRunnable c = (ControlRunnable)pool.firstElement();
pool.removeElement(c);
c.terminate();
currentThreadCount --;
}
}
}
/**
* Returns the thread to the pool.
* Called by threads as they are becoming idel.
*/
protected synchronized void returnController(ControlRunnable c) {
if(0 == currentThreadCount || stopThePool) {
c.terminate();
return;
}
currentThreadsBusy--;
pool.addElement(c);
notify();
}
/**
* Inform the pool that the specific thread finish.
*
* Called by the ControlRunnable.run() when the runnable
* throws an exception.
*/
protected synchronized void notifyThreadEnd(ControlRunnable c) {
currentThreadsBusy--;
currentThreadCount --;
notify();
}
/*
* Checks for problematic configuration and fix it.
* The fix provides reasonable settings for a single CPU
* with medium load.
*/
protected void adjustLimits() {
if(maxThreads <= 0) {
maxThreads = MAX_THREADS;
}
if(maxSpareThreads >= maxThreads) {
maxSpareThreads = maxThreads;
}
if(maxSpareThreads <= 0) {
if(1 == maxThreads) {
maxSpareThreads = 1;
} else {
maxSpareThreads = maxThreads/2;
}
}
if(minSpareThreads > maxSpareThreads) {
minSpareThreads = maxSpareThreads;
}
if(minSpareThreads <= 0) {
if(1 == maxSpareThreads) {
minSpareThreads = 1;
} else {
minSpareThreads = maxSpareThreads/2;
}
}
}
protected void openThreads(int toOpen) {
if(toOpen > maxThreads) {
toOpen = maxThreads;
}
if(0 == currentThreadCount) {
pool = new Vector(toOpen);
}
for(int i = currentThreadCount ; i < toOpen ; i++) {
pool.addElement(new ControlRunnable(this));
}
currentThreadCount = toOpen;
}
void log( String s ) {
loghelper.log(s);
}
/**
* Periodically execute an action - cleanup in this case
*/
class MonitorRunnable implements Runnable {
ThreadPool p;
Thread t;
boolean shouldTerminate;
MonitorRunnable(ThreadPool p) {
shouldTerminate = false;
this.p = p;
t = new Thread(this);
t.start();
}
public void run() {
while(true) {
try {
// Sleep for a while.
synchronized(this) {
this.wait(WORK_WAIT_TIMEOUT);
}
// Check if should terminate.
// termination happens when the pool is shutting down.
if(shouldTerminate) {
break;
}
// Harvest idle threads.
p.checkSpareControllers();
} catch(Throwable t) {
loghelper.log("Unexpected exception", t, Logger.ERROR);
}
}
}
/** Stop the monitor
*/
public synchronized void terminate() {
shouldTerminate = true;
this.notify();
}
}
/**
* A Thread object that executes various actions ( ThreadPoolRunnable )
* under control of ThreadPool
*/
class ControlRunnable implements Runnable {
/**
* ThreadPool where this thread will be returned
*/
ThreadPool p;
/**
* The thread that executes the actions
*/
Thread t;
/**
* The method that is executed in this thread
*/
ThreadPoolRunnable toRun;
/**
* Stop this thread
*/
boolean shouldTerminate;
/**
* Activate the execution of the action
*/
boolean shouldRun;
/**
* Per thread data - can be used only if all actions are
* of the same type.
* A better mechanism is possible ( that would allow association of
* thread data with action type ), but right now it's enough.
*/
boolean noThData;
Object thData[]=null;
/**
* Start a new thread, with no method in it
*/
ControlRunnable(ThreadPool p) {
toRun = null;
shouldTerminate = false;
shouldRun = false;
this.p = p;
t = new Thread(this);
t.start();
noThData=true;
thData=null;
}
public void run() {
while(true) {
try {
/* Wait for work. */
synchronized(this) {
if(!shouldRun && !shouldTerminate) {
this.wait();
}
}
if(toRun == null ) {
if( p.debug>0) p.log( "No toRun ???");
}
if( shouldTerminate ) {
if( p.debug>0) p.log( "Terminate");
break;
}
/* Check if should execute a runnable. */
try {
if(noThData) {
if(p.debug>0) p.log( "Getting new thread data");
thData=toRun.getInitData();
noThData = false;
}
if(shouldRun) {
toRun.runIt(thData);
}
} catch(Throwable t) {
loghelper.log("Caught exception executing " + toRun.toString() + ", terminating thread", t);
/*
* The runnable throw an exception (can be even a ThreadDeath),
* signalling that the thread die.
*
* The meaning is that we should release the thread from
* the pool.
*/
shouldTerminate = true;
shouldRun = false;
p.notifyThreadEnd(this);
} finally {
if(shouldRun) {
shouldRun = false;
/*
* Notify the pool that the thread is now idle.
*/
p.returnController(this);
}
}
/*
* Check if should terminate.
* termination happens when the pool is shutting down.
*/
if(shouldTerminate) {
break;
}
} catch(InterruptedException ie) { /* for the wait operation */
// can never happen, since we don't call interrupt
loghelper.log("Unexpected exception", ie);
}
}
}
public synchronized void runIt(ThreadPoolRunnable toRun) {
if( toRun == null ) {
throw new NullPointerException("No Runnable");
}
this.toRun = toRun;
shouldRun = true;
noThData = true;
this.notify();
}
public synchronized void terminate() {
shouldTerminate = true;
this.notify();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -