001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.axis2.util.threadpool;
021:
022: import edu.emory.mathcs.backport.java.util.concurrent.Executor;
023: import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue;
024: import edu.emory.mathcs.backport.java.util.concurrent.SynchronousQueue;
025: import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
026: import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
027: import org.apache.axis2.AxisFault;
028: import org.apache.axis2.i18n.Messages;
029: import org.apache.axis2.java.security.AccessController;
030: import org.apache.commons.logging.Log;
031: import org.apache.commons.logging.LogFactory;
032:
033: import java.security.PrivilegedActionException;
034: import java.security.PrivilegedExceptionAction;
035:
036: /**
037: * This the thread pool for axis2. This class will be used a singleton
038: * across axis2 engine. <code>ThreadPool</code> is accepts <code>AxisWorkers</code> which has
039: * run method on them and execute this method, using one of the threads
040: * in the thread pool.
041: */
042: public class ThreadPool implements ThreadFactory {
043: private static final Log log = LogFactory.getLog(ThreadPool.class);
044: protected static long SLEEP_INTERVAL = 1000;
045: private static boolean shutDown;
046: protected ThreadPoolExecutor executor;
047:
048: //integers that define the pool size, with the default values set.
049: private int corePoolSize = 5;
050: private int maxPoolSize = Integer.MAX_VALUE;
051:
052: public ThreadPool() {
053: setExecutor(createDefaultExecutor("Axis2 Task",
054: Thread.NORM_PRIORITY, true));
055: }
056:
057: public ThreadPool(int corePoolSize, int maxPoolSize) {
058: this .corePoolSize = corePoolSize;
059: this .maxPoolSize = maxPoolSize;
060: setExecutor(createDefaultExecutor("Axis2 Task",
061: Thread.NORM_PRIORITY, true));
062: }
063:
064: public Executor getExecutor() {
065: return executor;
066: }
067:
068: public void setExecutor(ThreadPoolExecutor executor) {
069: this .executor = executor;
070: }
071:
072: public void execute(Runnable worker) {
073: if (shutDown) {
074: throw new RuntimeException(Messages
075: .getMessage("threadpoolshutdown"));
076: }
077: executor.execute(worker);
078: }
079:
080: /**
081: * A forceful shutdown mechanism for thread pool.
082: */
083: public void forceShutDown() {
084: if (log.isDebugEnabled()) {
085: log
086: .debug("forceShutDown called. Thread workers will be stopped");
087: }
088: executor.shutdownNow();
089: }
090:
091: /**
092: * This is the recommended shutdown method for the thread pool
093: * This will wait till all the workers that are already handed over to the
094: * thread pool get executed.
095: *
096: * @throws org.apache.axis2.AxisFault
097: */
098: public void safeShutDown() throws AxisFault {
099: synchronized (this ) {
100: shutDown = true;
101: }
102:
103: executor.shutdown();
104: }
105:
106: protected ThreadPoolExecutor createDefaultExecutor(
107: final String name, final int priority, final boolean daemon) {
108: ThreadPoolExecutor rc;
109: if (maxPoolSize == Integer.MAX_VALUE) {
110: rc = new ThreadPoolExecutor(corePoolSize, maxPoolSize, 10,
111: TimeUnit.SECONDS, new SynchronousQueue(),
112: new DefaultThreadFactory(name, daemon, priority));
113: } else {
114: rc = new ThreadPoolExecutor(corePoolSize, maxPoolSize, 10,
115: TimeUnit.SECONDS, new LinkedBlockingQueue(),
116: new DefaultThreadFactory(name, daemon, priority));
117: }
118: rc.allowCoreThreadTimeOut(true);
119: return rc;
120: }
121:
122: private static class DefaultThreadFactory
123: implements
124: edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory {
125: private final String name;
126: private final boolean daemon;
127: private final int priority;
128:
129: public DefaultThreadFactory(String name, boolean daemon,
130: int priority) {
131: this .name = name;
132: this .daemon = daemon;
133: this .priority = priority;
134: }
135:
136: public Thread newThread(final Runnable runnable) {
137: // do the following section as privileged
138: // so that it will work even when java2 security
139: // has been enabled
140: Thread returnThread = null;
141: try {
142: returnThread = (Thread) AccessController
143: .doPrivileged(new PrivilegedExceptionAction() {
144: public Object run() {
145: Thread newThread = new Thread(runnable,
146: name);
147: newThread.setDaemon(daemon);
148: newThread.setPriority(priority);
149: return newThread;
150: }
151: });
152: } catch (PrivilegedActionException e) {
153: // note: inner class can't have its own static log variable
154: if (log.isDebugEnabled()) {
155: log
156: .debug(
157: "ThreadPoolExecutor.newThread(): Exception from AccessController ["
158: + e.getClass().getName()
159: + "] for ["
160: + e.getMessage() + "]", e);
161: }
162: }
163: return returnThread;
164:
165: }
166: }
167: }
|