001/* ---------------------------------------------------------------------------- 002 The Kiwi Toolkit - A Java Class Library 003 Copyright (C) 1998-2004 Mark A. Lindner 004 005 This library is free software; you can redistribute it and/or 006 modify it under the terms of the GNU General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This library is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 General Public License for more details. 014 015 You should have received a copy of the GNU General Public License 016 along with this library; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 02111-1307, USA. 019 020 The author may be contacted at: mark_a_lindner@yahoo.com 021 ---------------------------------------------------------------------------- 022 $Log: ResourcePool.java,v $ 023 Revision 1.5 2004/05/05 21:22:45 markl 024 Comment header updates. 025 026 Revision 1.4 2003/01/19 09:42:39 markl 027 Javadoc & comment header updates. 028 029 Revision 1.3 2001/06/26 06:10:40 markl 030 Fixed typo in javadoc. 031 032 Revision 1.2 2001/03/12 03:16:50 markl 033 *** empty log message *** 034 035 Revision 1.1 1999/04/23 07:33:25 markl 036 Initial revision 037 ---------------------------------------------------------------------------- 038*/ 039 040package kiwi.util; 041 042import java.util.*; 043 044/** An abstract class that represents a pool of instances of some resource. 045 * See <code>TimerPool</code> for an example concrete implementation. Accesses 046 * to the pool are threadsafe so there is no possibility of contention for 047 * the resource. 048 * 049 * @see kiwi.util.Resource 050 * @see kiwi.util.TimerPool 051 * 052 * @author Mark Lindner 053 */ 054 055public abstract class ResourcePool 056 { 057 private int size; 058 private Stack reservedList, availableList; 059 060 /** Construct a new <code>ResourcePool</code> of the given size. 061 * 062 * @param size The number of instances of a resource to preallocate in this 063 * pool. 064 */ 065 066 public ResourcePool(int size) 067 { 068 this.size = size; 069 reservedList = new Stack(); 070 availableList = new Stack(); 071 072 for(int i = 0; i < size; i++) 073 availableList.push(constructResource()); 074 } 075 076 /** Reserve one instance of the resource. If all instances are currently in 077 * use, this method blocks until one becomes available. 078 * 079 * @return An instance of the <code>Resource</code>. 080 */ 081 082 public synchronized Resource reserveResource() 083 { 084 for(;;) 085 { 086 if(!availableList.isEmpty()) 087 break; 088 089 try 090 { 091 System.err.println("All resource instances in use; waiting..."); 092 wait(); 093 } 094 catch(InterruptedException ex) 095 { 096 } 097 } 098 099 Resource resource = (Resource)availableList.pop(); 100 reservedList.push(resource); 101 resource.reserve(); 102 103 return(resource); 104 } 105 106 /** Release the given resource. If the resource is not currently reserved, 107 * this method does nothing. Note that it is the caller's responsibility 108 * to pass the correct resource to this method; the method does not check 109 * if the calling thread actually has the specified resource reserved. 110 * 111 * @param resource The <code>Resource</code> to release. 112 */ 113 114 public synchronized void releaseResource(Resource resource) 115 { 116 if(!(reservedList.contains(resource))) 117 throw(new IllegalArgumentException( 118 "Resource not managed by this pool!")); 119 120 reservedList.removeElement(resource); 121 resource.release(); 122 availableList.push(resource); 123 notify(); 124 } 125 126 /** Construct an instance of the resource that is managed by this pool. 127 * The constructor calls this method repeatedly to pre-build the number 128 * of instances specified as its argument. 129 * 130 * @return The newly-constructed <code>Resource</code> instance. 131 */ 132 133 abstract protected Resource constructResource(); 134 135 /** Get the total number of resource instances in this pool. 136 * 137 * @return The total number of instances. 138 */ 139 140 public int getTotalResourceCount() 141 { 142 return(size); 143 } 144 145 /** Get the number of resource instances that are currently in use. 146 * 147 * @return The number of instances that are in use. 148 */ 149 150 public synchronized int getUsedResourceCount() 151 { 152 return(reservedList.size()); 153 } 154 155 /** Get the number of resource instances that are currently available. 156 * 157 * @return The number of instances that are available. 158 */ 159 160 public synchronized int getAvailableResourceCount() 161 { 162 return(availableList.size()); 163 } 164 165 } 166 167/* end of source file */