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="6"> <jspp:jspshow value="http://www.koubei.com/city/11111111" time="1000"> </jspp:jspshow> <jspp:jspshow value="http://www.koubei.com/city/222222" time="2000"> </jspp:jspshow> <jspp:jspshow value="http://www.koubei.com/city/333333" time="3000"> </jspp:jspshow> <jspp:jspshow value="http://www.koubei.com/city/444444" time="4000"> </jspp:jspshow> <jspp:jspshow value="http://www.koubei.com/city/55555" time="5000"> </jspp:jspshow> <jspp:jspshow value="http://www.koubei.com/city/6666666" time="6000"> </jspp:jspshow> </jspp:multiThread> <% long ll = System.currentTimeMillis(); System.out.println(ll-l); %>
自定义标签的定义:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>2.2.3</tlib-version> <jsp-version>1.2</jsp-version> <short-name>jspp</short-name> <uri>/jspp-tags</uri> <display-name>"bigpipe Tags"</display-name> <description><![CDATA["jsp bigpipe"]]></description> <tag> <name>multiThread</name> <tag-class>JspMultiThreadTag</tag-class> <body-content>JSP</body-content> <description><![CDATA[duo xian cheng biaoqian]]></description> <attribute> <name>pageLetNum</name> <required>false</required> <rtexprvalue>false</rtexprvalue> <description><![CDATA[must equal to PageLet number]]></description> </attribute> </tag> <tag> <name>jspshow</name> <tag-class>JspShowTag</tag-class> <body-content>JSP</body-content> <description><![CDATA[PageLet model]]></description> <attribute> <name>value</name> <required>false</required> <rtexprvalue>false</rtexprvalue> <description><![CDATA[the string for show ]]></description> </attribute> <attribute> <name>time</name> <required>false</required> <rtexprvalue>false</rtexprvalue> <description><![CDATA[sleep time]]></description> </attribute> </tag> </taglib>