|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package com.sun.jmx.snmp.tasks; |
|
|
|
import java.util.ArrayList; |
|
import com.sun.jmx.snmp.tasks.Task; |
|
import com.sun.jmx.snmp.tasks.TaskServer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
**/ |
|
public class ThreadService implements TaskServer { |
|
|
|
public ThreadService(int threadNumber) { |
|
if (threadNumber <= 0) { |
|
throw new IllegalArgumentException("The thread number should bigger than zero."); |
|
} |
|
|
|
minThreads = threadNumber; |
|
threadList = new ExecutorThread[threadNumber]; |
|
|
|
priority = Thread.currentThread().getPriority(); |
|
cloader = Thread.currentThread().getContextClassLoader(); |
|
|
|
} |
|
|
|
// public methods |
|
// -------------- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**/ |
|
public void submitTask(Task task) throws IllegalArgumentException { |
|
submitTask((Runnable)task); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**/ |
|
public void submitTask(Runnable task) throws IllegalArgumentException { |
|
stateCheck(); |
|
|
|
if (task == null) { |
|
throw new IllegalArgumentException("No task specified."); |
|
} |
|
|
|
synchronized(jobList) { |
|
jobList.add(jobList.size(), task); |
|
|
|
jobList.notify(); |
|
} |
|
|
|
createThread(); |
|
} |
|
|
|
public Runnable removeTask(Runnable task) { |
|
stateCheck(); |
|
|
|
Runnable removed = null; |
|
synchronized(jobList) { |
|
int lg = jobList.indexOf(task); |
|
if (lg >= 0) { |
|
removed = jobList.remove(lg); |
|
} |
|
} |
|
if (removed != null && removed instanceof Task) |
|
((Task) removed).cancel(); |
|
return removed; |
|
} |
|
|
|
public void removeAll() { |
|
stateCheck(); |
|
|
|
final Object[] jobs; |
|
synchronized(jobList) { |
|
jobs = jobList.toArray(); |
|
jobList.clear(); |
|
} |
|
final int len = jobs.length; |
|
for (int i=0; i<len ; i++) { |
|
final Object o = jobs[i]; |
|
if (o!= null && o instanceof Task) ((Task)o).cancel(); |
|
} |
|
} |
|
|
|
|
|
public void terminate() { |
|
|
|
if (terminated == true) { |
|
return; |
|
} |
|
|
|
terminated = true; |
|
|
|
synchronized(jobList) { |
|
jobList.notifyAll(); |
|
} |
|
|
|
removeAll(); |
|
|
|
for (int i=0; i<currThreds; i++) { |
|
try { |
|
threadList[i].interrupt(); |
|
} catch (Exception e) { |
|
// TODO |
|
} |
|
} |
|
|
|
threadList = null; |
|
} |
|
|
|
// private classes |
|
// --------------- |
|
|
|
// A thread used to execute jobs |
|
|
|
private class ExecutorThread extends Thread { |
|
public ExecutorThread() { |
|
super(threadGroup, "ThreadService-"+counter++); |
|
setDaemon(true); |
|
|
|
|
|
this.setPriority(priority); |
|
this.setContextClassLoader(cloader); |
|
|
|
idle++; |
|
} |
|
|
|
public void run() { |
|
|
|
while(!terminated) { |
|
Runnable job = null; |
|
|
|
synchronized(jobList) { |
|
if (jobList.size() > 0) { |
|
job = jobList.remove(0); |
|
if (jobList.size() > 0) { |
|
jobList.notify(); |
|
} |
|
|
|
} else { |
|
try { |
|
jobList.wait(); |
|
} catch (InterruptedException ie) { |
|
// terminated ? |
|
} finally { |
|
} |
|
continue; |
|
} |
|
} |
|
if (job != null) { |
|
try { |
|
idle--; |
|
job.run(); |
|
} catch (Exception e) { |
|
|
|
e.printStackTrace(); |
|
} finally { |
|
idle++; |
|
} |
|
} |
|
|
|
|
|
this.setPriority(priority); |
|
Thread.interrupted(); |
|
this.setContextClassLoader(cloader); |
|
} |
|
} |
|
} |
|
|
|
|
|
private void stateCheck() throws IllegalStateException { |
|
if (terminated) { |
|
throw new IllegalStateException("The thread service has been terminated."); |
|
} |
|
} |
|
|
|
private void createThread() { |
|
if (idle < 1) { |
|
synchronized(threadList) { |
|
if (jobList.size() > 0 && currThreds < minThreads) { |
|
ExecutorThread et = new ExecutorThread(); |
|
et.start(); |
|
threadList[currThreds++] = et; |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
// protected or private variables |
|
|
|
private ArrayList<Runnable> jobList = new ArrayList<Runnable>(0); |
|
|
|
private ExecutorThread[] threadList; |
|
private int minThreads = 1; |
|
private int currThreds = 0; |
|
private int idle = 0; |
|
|
|
private boolean terminated = false; |
|
private int priority; |
|
private ThreadGroup threadGroup = new ThreadGroup("ThreadService"); |
|
private ClassLoader cloader; |
|
|
|
private static long counter = 0; |
|
|
|
private int addedJobs = 1; |
|
private int doneJobs = 1; |
|
} |