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.slf4j.Logger;
025 import org.slf4j.LoggerFactory;
026
027
028 /**
029 * Based class for WorkExecutorPool. Sub-classes define the synchronization
030 * policy (should the call block until the end of the work; or when it starts
031 * et cetera).
032 *
033 * @version $Rev: 723385 $ $Date: 2008-12-04 12:55:02 -0500 (Thu, 04 Dec 2008) $
034 */
035 public class WorkExecutorPoolImpl implements WorkExecutorPool {
036
037 /**
038 * A timed out pooled executor.
039 */
040 private ThreadPoolExecutor pooledExecutor;
041 private static Logger log = LoggerFactory.getLogger(WorkExecutorPoolImpl.class);
042
043 /**
044 * Creates a pool with the specified minimum and maximum sizes. The Channel
045 * used to enqueue the submitted Work instances is queueless synchronous
046 * one.
047 *
048 * @param maxSize Maximum size of the work executor pool.
049 */
050 public WorkExecutorPoolImpl(int maxSize) {
051 pooledExecutor = new ThreadPoolExecutor(1, maxSize, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
052 /*
053 FIXME: How to do this with concurrent.util ?
054 pooledExecutor.waitWhenBlocked();
055 */
056 }
057
058 /**
059 * Execute the specified Work.
060 *
061 * @param work Work to be executed.
062 */
063 public void execute(Runnable work) {
064 if(pooledExecutor.getPoolSize() == pooledExecutor.getMaximumPoolSize()) {
065 log.warn("Maximum Pool size has been exceeded. Current Pool Size = "+pooledExecutor.getMaximumPoolSize());
066 }
067
068 pooledExecutor.execute(work);
069 }
070
071 /**
072 * Gets the size of this pool.
073 */
074 public int getPoolSize() {
075 return pooledExecutor.getPoolSize();
076 }
077
078 /**
079 * Gets the maximum size of this pool.
080 */
081 public int getMaximumPoolSize() {
082 return pooledExecutor.getMaximumPoolSize();
083 }
084
085 /**
086 * Sets the maximum size of this pool.
087 * @param maxSize New maximum size of this pool.
088 */
089 public void setMaximumPoolSize(int maxSize) {
090 pooledExecutor.setMaximumPoolSize(maxSize);
091 }
092
093 public WorkExecutorPool start() {
094 throw new IllegalStateException("This pooled executor is already started");
095 }
096
097 /**
098 * Stops this pool. Prior to stop this pool, all the enqueued Work instances
099 * are processed. This is an orderly shutdown.
100 */
101 public WorkExecutorPool stop() {
102 int maxSize = getMaximumPoolSize();
103 pooledExecutor.shutdown();
104 return new NullWorkExecutorPool(maxSize);
105 }
106
107 }