双缓冲队列的java实现_超人_新浪博客

前段时间,做了个“双缓冲队列”,可是测试的效果就是不怎么明显,理论xx都在这里,可是就是看不到效果。
昨天在某某的提示下,终于意识到不该用阻塞队列,换成普通的List对象,这样效果就明显多啦~~
又重新写了一篇文档,如下
提出问题:为啥要有双缓冲队列?
引用09年9月《程序员》上的一句话:双缓冲队列就是冲着同步/互斥的开销来的。我们知道,在多个线程并发访问同一个资源的时候,需要特别注意线程的同步问题。稍稍不注意,哦活,程序结果不正确了。最经典的就是“银行取钱”的例子,想想,都跟现金挂上钩了,看来这真不容忽视。
今天我们要谈的不是如何去给资源加锁解锁来解决同步问题,今天的重点在于,如何将线程同步的开销降低到我们力所能及的程度。如果你觉得,你可以通过增加硬件资源来弥补程序开销,那么,你将不可能成为一个优秀的程序员。
进入正题,先引入一个例子,两个实体:一个是玩具工厂,它的工作就是不停地生产玩具;另外一个实体就是小孩,它的工作就是不停地从工厂拿玩具。小孩不可能直接到工厂去“拿”玩具吧?呵呵,妈妈是{jd1}不会放心的。所以,我们有一个“搬运工”,搬运工自然要具备“存放”的功能,不然他怎么将玩具带给小孩呢,是吧。所以,我们先将搬运工定义为一个List,用来存放工厂生产出来的玩具。

 
玩具类,定义一个玩具实体
public class Toy {
    private String name;

    public String getName() {
        return name;
    }
public void setName(String name) {
        this.name = name;
    }
}

 

生产玩具的玩具工厂,相当于生产者
package twoBufferQueue;


public class Factory extends Thread {
 public void run() {
  while (true) {

   Toy t = new Toy();

   t.setName("玩具");
   synchronized (Tools.lP) {
    if (Tools.lP.size() >= 2000) {
     try {
      Tools.lP.wait();
     } catch (Exception e) {
      // TODO: handle exception
     }
    }
    Tools.lP.add(t);
//    System.out.println("put one");
   }
  }

 }
}

小孩取玩具,相当于消费者

package twoBufferQueue;


public class Kid extends Thread {
 long time1 = System.currentTimeMillis();
 int count = 0;

 public void run() {
  while (true) {

   synchronized (Tools.lT) {
    if (Tools.lT.size() != 0){
     Tools.lT.remove(0);
     count++;
    }
     
   }
   
   if (count == 100000) {
    System.out.println("time:" + (System.currentTimeMillis() - time1));
    System.exit(0);
   }

  }
 }

}


双缓冲队列,里面有两个List

package twoBufferQueue;

import java.util.List;

public class DoubleBufferList {
 private List<Object> lP;
    private List<Object> lT;
    private int gap;

   
    public DoubleBufferList(List lP, List lT, int gap) {
        this.lP = lP;
        this.lT = lT;
        this.gap = gap;
    }

    public void check() {
        Runnable runner = new Runnable() {
            public void run() {
                while (true) {
                    if (lT.size() == 0) {
                        synchronized (lT) {
                            synchronized (lP) {
                                lT.addAll(lP);
                                lP.notifyAll();
                            }
                            lP.clear();
                          
                        }
                    }
                }
            }
        };
        Thread thread = new Thread(runner);
        thread.start();
    }

}


运行的主线程类:

package twoBufferQueue;

public class MainTest {
 public static void main(String[] args) {
  Factory f = new Factory();
        f.start();
        Kid k = new Kid();
        k.start();
        new DoubleBufferList(Tools.lP,Tools.lT,1).check();
 }
}

运行结果:time:265毫秒  确实很快,比用一个List的生产者消费者模型快很多,不至几倍...强烈建议大家使用。

已投稿到:
郑重声明:资讯 【双缓冲队列的java实现_超人_新浪博客】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——