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 */ 017package org.fusesource.hawtdispatch.util; 018 019import java.util.ArrayList; 020 021/** 022 * <p> 023 * </p> 024 * 025 * @author <a href="http://hiramchirino.com">Hiram Chirino</a> 026 */ 027abstract 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}