1 | // Copyright 2004-2007 Jean-Francois Poilpret |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | package net.sourceforge.hiveutils.collections.impl; |
16 | |
17 | import java.util.ArrayList; |
18 | import java.util.List; |
19 | |
20 | import org.apache.commons.logging.Log; |
21 | import org.apache.commons.logging.LogFactory; |
22 | |
23 | import net.sourceforge.hiveutils.collections.Queue; |
24 | |
25 | /** |
26 | * Implementation of <code>Queue</code> based on <code>ArrayList</code>. |
27 | * |
28 | * @author Jean-Francois Poilpret |
29 | */ |
30 | public class QueueImpl<T> implements Queue<T> |
31 | { |
32 | static private final Log _logger = LogFactory.getLog(QueueImpl.class); |
33 | |
34 | synchronized public boolean isEmpty() |
35 | { |
36 | return _list.isEmpty(); |
37 | } |
38 | |
39 | synchronized public void add(T o) |
40 | { |
41 | _list.add(o); |
42 | notifyAll(); |
43 | } |
44 | |
45 | synchronized public void unblock() |
46 | { |
47 | if (_waiting > 0) |
48 | { |
49 | _reset = true; |
50 | notifyAll(); |
51 | } |
52 | } |
53 | |
54 | public List<T> take() |
55 | { |
56 | return take(1); |
57 | } |
58 | |
59 | synchronized public List<T> take(int minCount) |
60 | { |
61 | _waiting++; |
62 | while ((_list.size() < minCount) && !_reset) |
63 | { |
64 | try |
65 | { |
66 | wait(); |
67 | } |
68 | catch (InterruptedException e) |
69 | { |
70 | _logger.warn("take", e); |
71 | } |
72 | } |
73 | List<T> list = new ArrayList<T>(_list); |
74 | _list.clear(); |
75 | _waiting--; |
76 | if (_waiting == 0) |
77 | { |
78 | _reset = false; |
79 | } |
80 | return list; |
81 | } |
82 | |
83 | public List<T> take(long timeout) |
84 | { |
85 | return take(1, timeout); |
86 | } |
87 | |
88 | synchronized public List<T> take(int minCount, long timeout) |
89 | { |
90 | if (timeout <= 0) |
91 | { |
92 | return take(minCount); |
93 | } |
94 | |
95 | _waiting++; |
96 | long actualTimeout = timeout; |
97 | long maxTime = System.currentTimeMillis() + actualTimeout; |
98 | while ((_list.size() < minCount) && (actualTimeout > 0) && !_reset) |
99 | { |
100 | try |
101 | { |
102 | wait(actualTimeout); |
103 | } |
104 | catch (InterruptedException e) |
105 | { |
106 | _logger.warn("take", e); |
107 | } |
108 | actualTimeout = maxTime - System.currentTimeMillis(); |
109 | } |
110 | List<T> list = new ArrayList<T>(_list); |
111 | _list.clear(); |
112 | _waiting--; |
113 | if (_waiting == 0) |
114 | { |
115 | _reset = false; |
116 | } |
117 | return list; |
118 | } |
119 | |
120 | private final List<T> _list = new ArrayList<T>(); |
121 | private boolean _reset = false; |
122 | private int _waiting = 0; |
123 | } |