001 /**
002 * Copyright (C) 2012 FuseSource, Inc.
003 * http://fusesource.com
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * 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 package org.fusesource.hawtdispatch.util;
018
019 import java.util.ArrayList;
020
021 /**
022 * <p>
023 * </p>
024 *
025 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
026 */
027 abstract public class ThreadLocalPool<T> {
028
029 class Pool {
030 final ArrayList<T> objects = new ArrayList<T>(maxPoolSizePerThread());
031 long hitCounter;
032 long missCounter;
033 // public void monitor() {
034 // DispatchQueue current = Dispatch.getCurrentThreadQueue();
035 // if( current!=null ) {
036 // current.executeAfter(1, TimeUnit.SECONDS, new Task() {
037 // @Override
038 // public void run() {
039 // if( hitCounter + missCounter > 0 ) {
040 // System.out.println(String.format("Pool stats: %d hits, %d misses = %f percent",
041 // hitCounter, missCounter, 100.0*hitCounter/(hitCounter + missCounter)));
042 // }
043 // hitCounter=0;
044 // missCounter=0;
045 // monitor();
046 // }
047 // });
048 // }
049 // }
050 }
051
052 private final ThreadLocal<Pool> objectsThreadLocal = new ThreadLocal<Pool>();
053
054 abstract protected T create();
055
056 protected int maxPoolSizePerThread() {
057 return 10;
058 }
059
060 private Pool getPool() {
061 Pool rc = objectsThreadLocal.get();
062 if (rc == null) {
063 rc = new Pool();
064 // rc.monitor();
065 objectsThreadLocal.set(rc);
066 }
067 return rc;
068 }
069
070 public T checkout() {
071 Pool pool = getPool();
072 ArrayList<T> objects = pool.objects;
073 if (!objects.isEmpty()) {
074 pool.hitCounter++;
075 return objects.remove(objects.size() - 1);
076 } else {
077 pool.missCounter++;
078 return create();
079 }
080 }
081
082 public void checkin(T value) {
083 ArrayList<T> objects = getPool().objects;
084 if (objects.size() < maxPoolSizePerThread()) {
085 objects.add(value);
086 }
087 }
088
089
090 }