001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.connector.work.pool;
019
020 import java.util.concurrent.LinkedBlockingQueue;
021 import java.util.concurrent.ThreadPoolExecutor;
022 import java.util.concurrent.TimeUnit;
023
024 import org.apache.commons.logging.Log;
025 import org.apache.commons.logging.LogFactory;
026
027 /**
028 * Based class for WorkExecutorPool. Sub-classes define the synchronization
029 * policy (should the call block until the end of the work; or when it starts
030 * et cetera).
031 *
032 * @version $Rev: 585608 $ $Date: 2007-10-17 19:56:54 +0200 (Wed, 17 Oct 2007) $
033 */
034 public class WorkExecutorPoolImpl implements WorkExecutorPool {
035
036 /**
037 * A timed out pooled executor.
038 */
039 private ThreadPoolExecutor pooledExecutor;
040 private static Log log = LogFactory.getLog(WorkExecutorPoolImpl.class);
041
042 /**
043 * Creates a pool with the specified minimum and maximum sizes. The Channel
044 * used to enqueue the submitted Work instances is queueless synchronous
045 * one.
046 *
047 * @param maxSize Maximum size of the work executor pool.
048 */
049 public WorkExecutorPoolImpl(int maxSize) {
050 pooledExecutor = new ThreadPoolExecutor(1, maxSize, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
051 /*
052 FIXME: How to do this with concurrent.util ?
053 pooledExecutor.waitWhenBlocked();
054 */
055 }
056
057 /**
058 * Execute the specified Work.
059 *
060 * @param work Work to be executed.
061 */
062 public void execute(Runnable work) {
063 if(pooledExecutor.getPoolSize() == pooledExecutor.getMaximumPoolSize()) {
064 log.warn("Maximum Pool size has been exceeded. Current Pool Size = "+pooledExecutor.getMaximumPoolSize());
065 }
066
067 pooledExecutor.execute(work);
068 }
069
070 /**
071 * Gets the size of this pool.
072 */
073 public int getPoolSize() {
074 return pooledExecutor.getPoolSize();
075 }
076
077 /**
078 * Gets the maximum size of this pool.
079 */
080 public int getMaximumPoolSize() {
081 return pooledExecutor.getMaximumPoolSize();
082 }
083
084 /**
085 * Sets the maximum size of this pool.
086 * @param maxSize New maximum size of this pool.
087 */
088 public void setMaximumPoolSize(int maxSize) {
089 pooledExecutor.setMaximumPoolSize(maxSize);
090 }
091
092 public WorkExecutorPool start() {
093 throw new IllegalStateException("This pooled executor is already started");
094 }
095
096 /**
097 * Stops this pool. Prior to stop this pool, all the enqueued Work instances
098 * are processed. This is an orderly shutdown.
099 */
100 public WorkExecutorPool stop() {
101 int maxSize = getMaximumPoolSize();
102 pooledExecutor.shutdown();
103 return new NullWorkExecutorPool(maxSize);
104 }
105
106 }