package org.playorm.nio.impl.libs; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.playorm.nio.api.libs.StartableExecutorService; import org.playorm.nio.api.mgmt.ExecutorServiceMBean; public class ExecutorServiceProxy implements StartableExecutorService, ExecutorServiceMBean { // private static final Logger log = Logger.getLogger(ExecutorServiceProxy.class.getName()); private ThreadPoolExecutor realSvc; private MyThreadFactory threadFactory; private int maximumPoolSize; private int corePoolSize; private boolean isDaemon = true; private String name; private int queueSize = 300; private long keepAliveTime = 5000; private boolean isRunning = false; public ExecutorServiceProxy(int numThreads) { this.maximumPoolSize = numThreads; this.corePoolSize = numThreads; } public synchronized void start(Object chanMgrId) { name = ""+chanMgrId; threadFactory = new MyThreadFactory(name, isDaemon); ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(queueSize); BlockingQueue<Runnable> blockingQueue = new MyBlockingQueue<Runnable>(queue); ThreadPoolExecutor svc = new ThreadPoolExecutor(maximumPoolSize, maximumPoolSize, keepAliveTime , TimeUnit.MILLISECONDS, blockingQueue, threadFactory); realSvc = svc; isRunning = true; } public synchronized void stop(Object chanMgrId) { if(realSvc != null) realSvc.shutdownNow(); realSvc = null; isRunning = false; } public synchronized void execute(Runnable command) { if(!isRunning) throw new IllegalStateException("This service was not started"); realSvc.execute(command); } //manageability stuff is below.... public boolean isRunning() { return isRunning; } public String getName() { return name; } public boolean isDaemonThreads() { return isDaemon; } public int getMaximumPoolSize() { return maximumPoolSize; } public synchronized void setMaximumPoolSize(int numThreads) { this.maximumPoolSize = numThreads; if(realSvc != null) realSvc.setMaximumPoolSize(maximumPoolSize); } public int getCorePoolSize() { return corePoolSize; } public synchronized void setCorePoolSize(int numThreads) { corePoolSize = numThreads; if(realSvc != null) realSvc.setCorePoolSize(corePoolSize); } public synchronized int getPoolSize() { if(realSvc != null) return realSvc.getPoolSize(); return -1; } public synchronized int getLargestPoolSize() { if(realSvc != null) return realSvc.getLargestPoolSize(); return -1; } public synchronized int getActiveCount() { if(realSvc != null) return realSvc.getActiveCount(); return 0; } public synchronized long getTaskCount() { if(realSvc != null) return realSvc.getTaskCount(); return 0; } public long getCompletedTaskCount() { if(realSvc != null) { return realSvc.getCompletedTaskCount(); } return -1; } public long getKeepAliveTime() { return keepAliveTime; } public synchronized void setKeepAliveTime(long time) { keepAliveTime = time; if(realSvc != null) realSvc.setKeepAliveTime(time, TimeUnit.MILLISECONDS); } public int getQueueSize() { return queueSize; } public void setQueueSize(int numElem) { this.queueSize = numElem; if(realSvc != null) { ExecutorService previous = realSvc; MyThreadFactory threadFactory = new MyThreadFactory(name, isDaemon); ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(queueSize); ThreadPoolExecutor svc = new ThreadPoolExecutor(maximumPoolSize, maximumPoolSize, keepAliveTime , TimeUnit.MILLISECONDS, queue, threadFactory); //switching to another executor likes this allows us not to have //to synchronize on putting things in the queue...(ie. the execute method) realSvc = svc; //now that the switch has been made, don't allow the one that is going away to //accept any more tasks, BUT allow those tasks to all complete previous.shutdown(); } } public synchronized int getRemainingCapacity() { if(realSvc != null) { BlockingQueue<Runnable> queue = (BlockingQueue<Runnable>)realSvc.getQueue(); return queue.remainingCapacity(); } return -1; } public synchronized int getCurrentSize() { if(realSvc != null) { BlockingQueue<Runnable> queue = (BlockingQueue<Runnable>)realSvc.getQueue(); return queue.size(); } return -1; } /** * @see org.playorm.nio.api.libs.StartableExecutorService#containsThread(java.lang.Thread) */ public boolean containsThread(Thread t) { return threadFactory.containsThread(t); } // public Set<Thread> getThreads() { // return threadFactory.getThreads(); // } }