View Javadoc

1   package org.apache.turbine.util.pool;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  /***
23   * Efficient array-based bounded buffer class.
24   * Adapted from CPJ, chapter 8, which describes design.
25   * Originally written by Doug Lea and released into the public domain.
26   * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>] <p>
27   *
28   * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
29   * @version $Id: BoundedBuffer.java 534527 2007-05-02 16:10:59Z tv $
30   */
31  public class BoundedBuffer
32  {
33      /*** The default capacity. */
34      public static final int DEFAULT_CAPACITY = 1024;
35  
36      protected final Object[] buffer;      // the elements
37  
38      protected int takePtr = 0;            // circular indices
39      protected int putPtr = 0;
40  
41      protected int usedSlots = 0;          // length
42      protected int emptySlots;             // capacity - length
43  
44      /***
45       * Creates a buffer with the given capacity.
46       *
47       * @param capacity the capacity.
48       * @throws IllegalArgumentException if capacity less or equal to zero.
49       */
50      public BoundedBuffer(int capacity)
51              throws IllegalArgumentException
52      {
53          if (capacity <= 0)
54          {
55              throw new IllegalArgumentException(
56                      "Bounded Buffer must have capacity > 0!");
57          }
58  
59          buffer = new Object[capacity];
60          emptySlots = capacity;
61      }
62  
63      /***
64       * Creates a buffer with the default capacity
65       */
66      public BoundedBuffer()
67      {
68          this(DEFAULT_CAPACITY);
69      }
70  
71      /***
72       * Returns the number of elements in the buffer.
73       * This is only a snapshot value, that may change
74       * immediately after returning.
75       *
76       * @return the size.
77       */
78      public synchronized int size()
79      {
80          return usedSlots;
81      }
82  
83      /***
84       * Returns the capacity of the buffer.
85       *
86       * @return the capacity.
87       */
88      public int capacity()
89      {
90          return buffer.length;
91      }
92  
93      /***
94       * Peeks, but does not remove the top item from the buffer.
95       *
96       * @return the object or null.
97       */
98      public synchronized Object peek()
99      {
100         return (usedSlots > 0)
101                 ? buffer[takePtr] : null;
102     }
103 
104     /***
105      * Puts an item in the buffer only if there is capacity available.
106      *
107      * @param item the item to be inserted.
108      * @return true if accepted, else false.
109      */
110     public synchronized boolean offer(Object x)
111     {
112         if (x == null)
113         {
114             throw new IllegalArgumentException("Bounded Buffer cannot store a null object");
115         }
116 
117         if (emptySlots > 0)
118         {
119             --emptySlots;
120             buffer[putPtr] = x;
121             if (++putPtr >= buffer.length)
122             {
123                 putPtr = 0;
124             }
125             usedSlots++;
126             return true;
127         }
128         else
129         {
130             return false;
131         }
132     }
133 
134     /***
135      * Polls and removes the top item from the buffer if one is available.
136      *
137      * @return the oldest item from the buffer, or null if the buffer is empty.
138      */
139     public synchronized Object poll()
140     {
141         if (usedSlots > 0)
142         {
143             --usedSlots;
144             Object old = buffer[takePtr];
145             buffer[takePtr] = null;
146             if (++takePtr >= buffer.length)
147             {
148                 takePtr = 0;
149             }
150             emptySlots++;
151             return old;
152         }
153         else
154         {
155             return null;
156         }
157     }
158 }