日期:2014-05-16  浏览次数:20386 次

jsp标签实现facebook的BigPipe
   facebook的bigpipe,使页面的加载速度加快。并且可以用来替换ajax。
   具体的介绍以及stutrus2版本的可以参考
    http://www.ibm.com/developerworks/cn/java/j-lo-bigpipe/
    上面有相当大的篇幅是介绍原理、效果的。以及相应的stutrus2源码下载。
   
    在这里,我实现了jsp的自定义标签的多线程版本。

    使用后的效果是6秒多。
    如果没有使用多线程。每个模块都是单独加载的话,即使用前是21秒。


/**
 * bigpipe包围的标签。
 * 在标签内的相应的标签,可以用多线程来加载。
 * 
 * bigpipe的多线程容器。
 *
 * @author shanzhu
 * @version 1.0 2011-10-11
 */

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class JspMultiThreadTag extends BodyTagSupport{

    /**
     * 
     */
    private static final long serialVersionUID = 844627840543112685L;

    //多线程容器
    public static ExecutorService exe = Executors.newFixedThreadPool(20);
    //有多个分割PageLet需要加载,这个必须与jsp页面上的分割PageLet对象的数目一致。
    private String pageLetNum;
    public static final String COUNT_DOWN1 = "countDown1";

    @Override
    public int doEndTag() throws JspException {
        CountDownLatch c = (CountDownLatch)pageContext.getRequest().getAttribute(COUNT_DOWN1);
        try {
            c.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return super.doEndTag();
    }

    @Override
    public int doStartTag() throws JspException {
        //CountDownLatch如其所写,是一个倒计数的锁存器,当计数减至0时触发特定的事件。
        CountDownLatch countDownLatch = new CountDownLatch(Integer.parseInt(pageLetNum));   
        pageContext.getRequest().setAttribute(COUNT_DOWN1, countDownLatch);
        return super.doStartTag();
    }

    public String getPageLetNum() {
        return pageLetNum;
    }

    public void setPageLetNum(String pageLetNum) {
        this.pageLetNum = pageLetNum;
    }   
    
    
}
/**
 * 具体的每个线程处理
 *
 * @author shanzhu
 * @version 1.0 2011-10-11
 */

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class JspShowTag extends BodyTagSupport{

    /**
     * 
     */
    private static final long serialVersionUID = -1293048704943284655L;
    private String value;//显示的字符串的值
    private int time;//休眠的时间

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }

    @Override
    public int doEndTag() throws JspException {
       int end = super.doEndTag();
        JspMultiThreadTag.exe.execute(new Runnable() {
            
            @Override
            public void run() {
                CountDownLatch c = (CountDownLatch)pageContext.getRequest().getAttribute(JspMultiThreadTag.COUNT_DOWN1);
                try {
                    try {
                        Thread.sleep(time);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    pageContext.getOut().write(value);
                    pageContext.getOut().flush();   //刷新缓冲区。如果调试的时候,可以把这段代码注释后对比效果。
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                c.countDown();//减一
            }
        });
        
        return end;
    }

}


在相对应的jsp页面
<%@taglib prefix="jspp" uri="/jspp-tags"%>
<% long l = System.currentTimeMillis(); %>
<jspp:multiThread pageLetNum="