01: /*
02: * Copyright 2004 Clinton Begin
03: *
04: * Licensed under the Apache License, Version 2.0 (the "License");
05: * you may not use this file except in compliance with the License.
06: * You may obtain a copy of the License at
07: *
08: * http://www.apache.org/licenses/LICENSE-2.0
09: *
10: * Unless required by applicable law or agreed to in writing, software
11: * distributed under the License is distributed on an "AS IS" BASIS,
12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13: * See the License for the specific language governing permissions and
14: * limitations under the License.
15: */
16: package com.ibatis.common.util;
17:
18: /**
19: * This is to help keep from getting too many resources
20: */
21: public class Throttle {
22:
23: private final Object LOCK = new Object();
24:
25: private int count;
26: private int limit;
27: private long maxWait;
28:
29: /**
30: * Create a throttle object with just a limit
31: * @param limit - the number of references to allow
32: */
33: public Throttle(int limit) {
34: this .limit = limit;
35: this .maxWait = 0;
36: }
37:
38: /**
39: * Create a throttle object with a limit and a wait time
40: * @param limit - the number of references to allow
41: * @param maxWait - the maximum wait time allowed for a reference
42: */
43: public Throttle(int limit, long maxWait) {
44: this .limit = limit;
45: this .maxWait = maxWait;
46: }
47:
48: /**
49: * Add a reference; if a reference is not available, an exception is thrown
50: */
51: public void increment() {
52: synchronized (LOCK) {
53: long totalWaitTime = 0;
54: while (count >= limit) {
55: if (maxWait > 0) {
56: long waitTime = System.currentTimeMillis();
57: try {
58: LOCK.wait(maxWait - totalWaitTime);
59: } catch (InterruptedException e) {
60: //ignore
61: }
62: totalWaitTime += System.currentTimeMillis()
63: - waitTime;
64: if (totalWaitTime > maxWait) {
65: throw new RuntimeException(
66: "Throttle waited too long ("
67: + totalWaitTime
68: + " milliseconds) for lock.");
69: }
70: } else {
71: try {
72: LOCK.wait();
73: } catch (InterruptedException e) {
74: //ignore
75: }
76: }
77: }
78: count++;
79: }
80: }
81:
82: /**
83: * Remove a reference
84: */
85: public void decrement() {
86: synchronized (LOCK) {
87: count--;
88: LOCK.notify();
89: }
90: }
91: }
|