环形缓冲区(JAVA数组实现)

来源:互联网 发布:进销存软件怎么制作 编辑:程序博客网 时间:2024/04/30 04:00

环形缓冲区(JAVA数组实现)

分类: toys 165人阅读 评论(0)收藏 举报
view plainprint?
  1. ///////////////////////////////////////////////////////////////////////////////  
  2. /////// 写了个小玩意 — ascii字符“播放器“,其实也只需要解决个缓冲问题,         ///////  
  3. /////// 因我很无耻地认为这个环形缓冲还有其它用武之地,                        ///////  
  4. /////// 于是贴上来了。 接受考验~ 请不吝BS~                                  ///////  
  5. /////// main方法只是个使用例子,可以删除之。                                 ///////  
  6. ///////////////////////////////////////////////////////////////////////////////  
  7. package freer.Cupenoruler.until;  
  8.   
  9. import java.io.BufferedReader;  
  10. import java.io.File;  
  11. import java.io.FileNotFoundException;  
  12. import java.io.FileReader;  
  13. import java.io.IOException;  
  14.   
  15. /** 
  16.  * 环形缓冲区(数组实现),逻辑上缓冲区是首位衔接着,像个圆圈一样。 
  17.  *  
  18.  * @author Cupenoruler@foxmail.com 
  19.  * @version 2011-11-22 
  20.  */  
  21. public class CircularBuffer<T> {  
  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 ThreadState putThreadState = ThreadState.RUNNING;  
  30.     private ThreadState getThreadState = ThreadState.RUNNING;  
  31.       
  32.     /*************************************************\ 
  33.      *            仅作测试之用,可删除此方法          * 
  34.      * 小子这里仅有6000多个txt文本,基本凑合  * 
  35.     \************************************************/  
  36.     public static void main(String[] shit) {  
  37.           
  38.         //拿到源文件列表  
  39.         String txtsPath = "D:/Backup/workbench/ASCII_Player/resource/txt";  
  40.         final File[] fileSource = new File(txtsPath).listFiles();  
  41.           
  42.         final CircularBuffer<String> cBuffer = new CircularBuffer<String>(2048);  
  43.           
  44.         //专业的读文本线程  
  45.         Thread putThread =   
  46.             new Thread() {  
  47.                 public void run() {  
  48.                     StringBuilder tempBuilder = new StringBuilder(4096); //文本缓冲  
  49.                     BufferedReader tempReader = null;  
  50.                     String        tempString  = null;  
  51.                       
  52.                     try {  
  53.                         /* 挨个读取文本 */  
  54.                         for(File temp : fileSource) {  
  55.                             tempBuilder.delete(0, tempBuilder.length()); //清空builder   
  56.                             tempReader = new BufferedReader( new FileReader(temp) );  
  57.                               
  58.                             whilenull != (tempString = tempReader.readLine()) ){  
  59.                                 tempBuilder.append(tempString);  
  60.                                 tempBuilder.append("\n");  
  61.                             }  
  62.                             cBuffer.putElement(tempBuilder.toString()); //build完成,入库  
  63.                         }  
  64.                         tempReader.close(); //读完收工  
  65.                           
  66.                     } catch (FileNotFoundException e) {  
  67.                         e.printStackTrace();  
  68.                         System.out.println("文件不存在,txtsPath可能有误");  
  69.                       
  70.                     } catch (IOException e) {  
  71.                         e.printStackTrace();  
  72.                         System.out.println("tempReader挂球");  
  73.   
  74.                     }  
  75.                     cBuffer.setPutThreadState(ThreadState.OVER); //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.                 Thread.sleep(20);  
  93.             } catch (InterruptedException e) {  
  94.                 e.printStackTrace();  
  95.             }  
  96.         }  
  97.     }  
  98.       
  99.     /** 
  100.      * 指定长度的缓冲区 
  101.      * @param capacity 
  102.      */  
  103.     public CircularBuffer(int capacity) {  
  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 putElement( T element) {  
  113.         // 有空位就插入~  
  114.         // 没空位就轮询,直到有空位可插入为止~  
  115.         while (null != this.buffer[this.indexForPut]) {  
  116.             try {  
  117.                 this.setPutThreadState(ThreadState.BLOCK); // put线程标记为:阻塞  
  118.                 Thread.sleep(100);  
  119.   
  120.             } catch (InterruptedException e) {  
  121.                 e.printStackTrace(); // 例行公事  
  122.                 System.out.println("线程意外停止,正在检查");  
  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 T getElement() {  
  140.         // 有元素就拿出~  
  141.         // 没元素就轮询,直到有元素可拿为止~ 若是put完毕、 数据取空,则返回null以告知调用者   
  142.         while (null == this.buffer[this.indexForGet]) {  
  143.             try {  
  144.                 this.setGetThreadState(ThreadState.BLOCK); // get线程标记为:阻塞         
  145.                 ifthis.isPutedOver()&& this.isEmputy() ){  
  146.                     this.setGetThreadState(ThreadState.OVER);  
  147.                     return null;  
  148.                 }  
  149.                 Thread.sleep(100);  
  150.   
  151.             } catch (InterruptedException e) {  
  152.                 e.printStackTrace();  
  153.                 System.out.println("线程意外停止");  
  154.   
  155.             }  
  156.         }  
  157.         this.setGetThreadState(ThreadState.RUNNING); // get线程标记为:正在运行  
  158.           
  159.         /* 拿到元素,buffer腾出该元素位,将get索引指向下一元素~ */  
  160.         Object temp = 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 isEmputy(){  
  176.         // 新元素是以 索引0 向 索引length 的顺序 put入  
  177.         // 有鉴于此,这里倒过来枚举,防止出现“同向追赶”导致落空的的囧事;  
  178.         for(int i = this.buffer.length-1; i > 0; i--){  
  179.             ifthis.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 isAllBlock(){  
  191.         return ( this.getThreadState == ThreadState.BLOCK  
  192.                &&this.putThreadState == ThreadState.BLOCK );  
  193.     }  
  194.       
  195.     /** 
  196.      * 检查数据源是否缓冲完毕 
  197.      * @return boolean true-完成  false-未完成 
  198.      */  
  199.     public boolean isPutedOver(){  
  200.         return  this.putThreadState == ThreadState.OVER;  
  201.     }  
  202.   
  203.     public void setPutThreadState(ThreadState putThreadState) {  
  204.         this.putThreadState = putThreadState;  
  205.     }  
  206.   
  207.     private void setGetThreadState(ThreadState getThreadState) {  
  208.         this.getThreadState = getThreadState;  
  209.     }  
  210.   
  211. }  
  212.   
  213. /** 
  214.  * 线程的几种状态 
  215.  * @author Cupenoruler@foxmai.com 
  216.  * @version 2011-11-22 
  217.  */  
  218. enum ThreadState{  
  219.     BLOCK,      /*暂时阻塞*/  
  220.     RUNNING,    /*运行*/  
  221.     OVER,       /*线程顺利完成*/  
  222.     INTERRUPT   /*中断,(暂时用不到)*/  


原创粉丝点击