环形缓冲区(JAVA数组实现)
1. ///
2. /// 写了个小玩意 — ascii字符“播放器“,其实也只需要解决个缓冲问题, ///
3. /// 因我很无耻地认为这个环形缓冲还有其它用武之地, ///
4. /// 于是贴上来了。 接受考验~ 请不吝BS~ ///
5. /// main方法只是个使用例子,可以删除之。 ///
6. ///
7. package
8.
9. import
10. import
11. import
12. import
13. import
14.
15. /**
16. * 环形缓冲区(数组实现),逻辑上缓冲区是首位衔接着,像个圆圈一样。
17. *
18. * @author Cupenoruler@foxmail.com
19. * @version 2011-11-22
20. */
21. public class
22.
23. private Object[] buffer = null; // 数据容器
24. private int capacity = 0; // 缓冲区长度
25. private int indexForPut = 0; // put索引 (下一个要写入的位置)
26. private int indexForGet = 0; // get索引 (下一个要读取的位置)
27.
28. /* put 和 get 的线程状态标记 */
29. private
30. private
31.
32. /*************************************************\
33. * 仅作测试之用,可删除此方法 *
34. * 小子这里仅有6000多个txt文本,基本凑合 *
35. \************************************************/
36. public static void
37.
38. //拿到源文件列表
39. "D:/Backup/workbench/ASCII_Player/resource/txt";
40. final File[] fileSource = new
41.
42. final CircularBuffer<String> cBuffer = new CircularBuffer<String>(2048);
43.
44. //专业的读文本线程
45. Thread putThread =
46. new
47. public void
48. new StringBuilder(4096); //文本缓冲
49. null;
50. null;
51.
52. try
53. /* 挨个读取文本 */
54. for(File temp : fileSource) {
55. 0, tempBuilder.length()); //清空builder
56. new BufferedReader( new
57.
58. while( null
59. tempBuilder.append(tempString);
60. "\n");
61. }
62. //build完成,入库
63. }
64. //读完收工
65.
66. catch
67. e.printStackTrace();
68. "文件不存在,txtsPath可能有误");
69.
70. catch
71. e.printStackTrace();
72. "tempReader挂球");
73.
74. }
75. //put线程标记为:完成
76. }
77. };
78.
79. /* 开动put线程……………… */
80. putThread.start();
81.
82. /* get线程(当前线程 ) */
83. while(true){
84. String temp = cBuffer.getElement();
85. if(temp == null){
86. break;
87. else
88. System.out.println(temp);
89. }
90.
91. try
92. 20);
93. catch
94. e.printStackTrace();
95. }
96. }
97. }
98.
99. /**
100. * 指定长度的缓冲区
101. * @param capacity
102. */
103. public CircularBuffer(int
104. this.capacity = capacity;
105. this.buffer = new String[this.capacity];
106. }
107.
108. <pre name="code" class="java"> /**
109. * 写入数据,注意此函数会导致阻塞
110. * @param element
111. */
112. public void
113. // 有空位就插入~
114. // 没空位就轮询,直到有空位可插入为止~
115. while (null != this.buffer[this.indexForPut]) {
116. try
117. this.setPutThreadState(ThreadState.BLOCK); // put线程标记为:阻塞
118. 100);
119.
120. catch
121. // 例行公事
122. "线程意外停止,正在检查");
123.
124. }
125. }
126. this.setPutThreadState(ThreadState.RUNNING); // put线程标记为:正在运行
127.
128. // 填入元素,将put索引指向下一元素位~
129. this.buffer[this.indexForPut] = element;
130. this.indexForPut++;
131. this.indexForPut %= this.capacity;
132. }
133.
134. /**
135. * 取数据,注意此函数会阻塞,若put线程结束且缓冲区为空时函数会返回null
136. * @return 下一个T元素 或者 null
137. */
138. @SuppressWarnings("unchecked")
139. public
140. // 有元素就拿出~
141. // 没元素就轮询,直到有元素可拿为止~ 若是put完毕、 数据取空,则返回null以告知调用者
142. while (null == this.buffer[this.indexForGet]) {
143. try
144. this.setGetThreadState(ThreadState.BLOCK); // get线程标记为:阻塞
145. if( this.isPutedOver()&& this.isEmputy() ){
146. this.setGetThreadState(ThreadState.OVER);
147. return null;
148. }
149. 100);
150.
151. catch
152. e.printStackTrace();
153. "线程意外停止");
154.
155. }
156. }
157. this.setGetThreadState(ThreadState.RUNNING); // get线程标记为:正在运行
158.
159. /* 拿到元素,buffer腾出该元素位,将get索引指向下一元素~ */
160. this.buffer[this.indexForGet];
161. this.buffer[this.indexForGet] = null;
162. this.indexForGet++;
163. this.indexForGet %= this.capacity;
164.
165. return (T)temp; // 返回拿到的元素引用
166. }
167.
168. /****************************************************\
169. * --Setter and Getter-- *
170. \****************************************************/
171. /**
172. * 检查此环形缓冲区是否为空
173. * @return boolean true则表示为空,false则不为空
174. */
175. public boolean
176. // 新元素是以 索引0 向 索引length 的顺序 put入
177. // 有鉴于此,这里倒过来枚举,防止出现“同向追赶”导致落空的的囧事;
178. for(int i = this.buffer.length-1; i > 0; i--){
179. if( this.buffer[i] != null
180. return false;
181. }
182. }
183. return true;
184. }
185.
186. /**
187. * 检查 put 线程和 get 线程是否同时阻塞,
188. * @return boolean true-挂球 false-良好
189. */
190. public boolean
191. return ( this.getThreadState == ThreadState.BLOCK
192. this.putThreadState == ThreadState.BLOCK );
193. }
194.
195. /**
196. * 检查数据源是否缓冲完毕
197. * @return boolean true-完成 false-未完成
198. */
199. public boolean
200. return this.putThreadState == ThreadState.OVER;
201. }
202.
203. public void
204. this.putThreadState = putThreadState;
205. }
206.
207. private void
208. this.getThreadState = getThreadState;
209. }
210.
211. }
212.
213. /**
214. * 线程的几种状态
215. * @author Cupenoruler@foxmai.com
216. * @version 2011-11-22
217. */
218. enum
219. /*暂时阻塞*/
220. /*运行*/
221. /*线程顺利完成*/
222. /*中断,(暂时用不到)*/
223. }