|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
再说说缺点:首先java功能强大的背后是其复杂性,就拿web来说,当今流行的框架有很多,什么struts,spring,jQuery等等,而这无疑增加了java的复杂性。js|编程|计划 很多Web使用、企业使用触及到长工夫的操纵,比方庞大的数据库查询或沉重的XML处置等,固然这些义务次要由数据库体系或两头件完成,但义务实行的了局仍然要借助JSP才干发送给用户。本文先容了一种经由过程改善前端体现层来改良用户感到、加重服务器负载的举措。
当JSP挪用一个必需长工夫运转的操纵,且该操纵的了局不克不及(在服务器端)缓冲,用户每次哀求该页面时都必需长工夫守候。良多时分,用户会得到耐烦,接着实验点击扫瞄器的革新按钮,终极扫兴地分开。
本文先容的手艺是把沉重的盘算义务分别开来,由一个自力的线程运转,从而办理上述成绩。当用户挪用JSP页面时,JSP页面会当即前往,并提醒用户义务已启动且正在实行;JSP页面主动革新本人,呈报在自力线程中运转的沉重盘算义务确当行进度,直至义务完成。
1、摹拟义务
起首我们计划一个TaskBean类,它完成java.lang.Runnable接口,其run()办法在一个由JSP页面(start.jsp)启动的自力线程中运转。停止run()办法实行由另外一个JSP页面stop.jsp卖力。TaskBean类还完成了java.io.Serializable接口,如许JSP页面就能够将它作为JavaBean挪用:
- packagetest.barBean;importjava.io.Serializable;publicclassTaskBeanimplementsRunnable,Serializable{privateintcounter;privateintsum;privatebooleanstarted;privatebooleanrunning;privateintsleep;publicTaskBean(){counter=0;sum=0;started=false;running=false;sleep=100;}}
复制代码
TaskBean包括的“沉重义务”是盘算1+2+3…+100的值,不外它欠亨过100*(100+1)/2=5050公式盘算,而是由run()办法挪用work()办法100次完成盘算。work()办法的代码以下所示,个中挪用Thread.sleep()是为了确保义务总耗时约10秒。
- protectedvoidwork(){try{Thread.sleep(sleep);counter++;sum+=counter;}catch(InterruptedExceptione){setRunning(false);}}
复制代码
status.jsp页面经由过程挪用上面的getPercent()办法取得义务的完成情况:
- publicsynchronizedintgetPercent(){returncounter;}
复制代码
假如义务已启动,isStarted()办法将前往true:
- publicsynchronizedbooleanisStarted(){returnstarted;}
复制代码
假如义务已完成,isCompleted()办法将前往true:
- publicsynchronizedbooleanisCompleted(){returncounter==100;}
复制代码
假如义务正在运转,isRunning()办法将前往true:
- publicsynchronizedbooleanisRunning(){returnrunning;}
复制代码
SetRunning()办法由start.jsp或stop.jsp挪用,当running参数是true时。SetRunning()办法还要将义务标志为“已启动”。挪用setRunning(false)暗示请求run()办法中断实行。
- publicsynchronizedvoidsetRunning(booleanrunning){this.running=running;if(running)started=true;}
复制代码
义务实行终了后,挪用getResult()办法前往盘算了局;假如义务还没有实行终了,它前往null:
- publicsynchronizedObjectgetResult(){if(isCompleted())returnnewInteger(sum);elsereturnnull;}
复制代码
当running标志为true、completed标志为false时,run()办法挪用work()。在实践使用中,run()办法大概要实行庞大的SQL查询、剖析年夜型XML文档,大概挪用损耗大批CPU工夫的EJB办法。注重“沉重的义务”大概要在远程服务器上实行。呈报了局的JSP页面有两种选择:大概守候义务停止,大概利用一个进度条。
- publicvoidrun(){try{setRunning(true);while(isRunning()&&!isCompleted())work();}finally{setRunning(false);}}
复制代码
2、启动义务
start.jsp是web.xml部署形貌符中声明的接待页面,web.xml的内容是:
- <?xmlversion="1.0"encoding="GB2312"?><!DOCTYPEweb-appPUBLIC"-//SunMicrosystems,Inc.//DTDWebApplication2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><welcome-file-list><welcome-file>start.jsp</welcome-file></welcome-file-list></web-app>
复制代码
start.jsp启动一个公用的线程来运转“沉重的义务”,然后把HTTP哀求传送给status.jsp。
start.jsp页面使用标志创立一个TaskBean的实例,将scope属性界说为session使得关于来自统一扫瞄器的HTTP哀求,其他页面也能提取到统一个Bean对象。start.jsp经由过程挪用session.removeAttribute("task")确保创立了一个新的Bean对象,而不是提取一个旧对象(比方,统一个用户会话中更早的JSP页面所创立的Bean对象)。
上面是start.jsp页面的代码清单:
- <%session.removeAttribute("task");%><jsp:useBeanid="task"scope="session"class="test.barBean.TaskBean"/><%task.setRunning(true);%><%newThread(task).start();%><jsp:forwardpage="status.jsp"/>
复制代码 start.jsp创立并设置好TaskBean对象以后,接着创立一个Thread,并将Bean对象作为一个Runnable实例传进。挪用start()办法时新创立的线程将实行TaskBean对象的run()办法。
如今有两个线程在并发实行:实行JSP页面的线程(称之为“JSP线程”),由JSP页面创立的线程(称之为“义务线程”)。接上去,start.jsp使用挪用status.jsp,status.jsp显现出进度条和义务的实行情形。注重status.jsp和start.jsp在统一个JSP线程中运转。
start.jsp在创立线程之前就把TaskBean的running标志设置成了true,如许,即便当JSP线程已入手下手实行status.jsp而义务线程的run()办法还没有启动,也可以确保用户会失掉“义务已入手下手运转”的形态呈报。
将running标志设置成true、启动义务线程这两行代码能够移进TaskBean组成一个新的办法,然后由JSP页面挪用这个新办法。一样平常而言,JSP页面应该只管罕用Java代码,即我们应该尽量地把Java代码放进Java类。不外本例中我们不服从这一划定规矩,把newThread(task).start()间接放进start.jsp凸起标明JSP线程创立并启动了义务线程。
在JSP页面中操纵多线程必需审慎,注重JSP线程和别的线程实践上是并发实行的,就象在桌面使用程序中,我们用一个线程来处置GUI事务,别的再用一个或多个线程来处置背景义务。
不外在JSP情况中,思索到多个用户同时哀求某一个页面的情形,统一个JSP页面大概会在多个线程中同时运转;别的,偶然统一个用户大概会向统一个页面收回多个哀求,固然这些哀求来自统一个用户,它们也会招致服务器同时运转一个JSP页面的多个线程。
3、义务进度
status.jsp页面使用一个HTML进度条向用户显现义务的实行情形。起首,status.jsp使用标志取得start.jsp页面创立的Bean对象:
- <jsp:useBeanid="task"scope="session"class="test.barBean.TaskBean"/>
复制代码 为了实时反应义务实行进度,status.jsp会主动革新。JavaScript代码setTimeout("location=′status.jsp′",1000)将每隔1000毫秒革新页面,从头哀求status.jsp,不必要用户干涉。 - <HTML><HEAD><TITLE>JSP进度条</TITLE><%if(task.isRunning()){%><SCRIPTLANGUAGE="JavaScript">setTimeout("location=′status.jsp′",1000);</SCRIPT><%}%></HEAD><BODY>
复制代码 进度条实践上是一个HTML表格,包括10个单位,即每一个单位代表义务整体的10%进度。 - <H1ALIGN="CENTER">JSP进度条</H1><H2ALIGN="CENTER">
复制代码 了局: - <%=task.getResult()%><BR><%intpercent=task.getPercent();%><%=percent%>%</H2><TABLEWIDTH="60%"ALIGN="CENTER"BORDER=1CELLPADDING=0CELLSPACING=2><TR><%for(inti=10;i<=percent;i+=10){%><TDWIDTH="10%"BGCOLOR="#000080"></TD><%}%><%for(inti=100;i>percent;i-=10){%><TDWIDTH="10%"></TD><%}%></TR></TABLE>
复制代码 义务实行情形分上面几种形态:正在实行,已完成,还没有入手下手,已中断: - <TABLEWIDTH="100%"BORDER=0CELLPADDING=0CELLSPACING=0><TR><TDALIGN="CENTER"><%if(task.isRunning()){%>
复制代码 正在实行 - <%}else{%><%if(task.isCompleted()){%>
复制代码 完成 - <%}elseif(!task.isStarted()){%>
复制代码 还没有入手下手 已中断 页面底部供应了一个按钮,用户能够用它来中断或从头启动义务: - <TR><TDALIGN="CENTER"><BR><%if(task.isRunning()){%><FORMMETHOD="GET"ACTION="stop.jsp"><INPUTTYPE="SUBMIT"VALUE="中断"></FORM><%}else{%><FORMMETHOD="GET"ACTION="start.jsp"><INPUTTYPE="SUBMIT"VALUE="入手下手"></FORM><%}%></TD></TR></TABLE></BODY></HTML>
复制代码 只需一直止义务,约10秒后扫瞄器将显现出盘算了局5050:
4、中断义务
stop.jsp页面把running标志设置成false,从而中断以后的盘算义务: - <jsp:useBeanid="task"scope="session"class="test.barBean.TaskBean"/><%task.setRunning(false);%><jsp:forwardpage="status.jsp"/>
复制代码 注重最早的Java版本供应了Thread.stop办法,但JDK从1.2版入手下手已不同意利用Thread.stop办法,以是我们不克不及间接挪用Thread.stop()。
第一次运转本文程序的时分,你会看就任务的启动有点提早;一样地,第一次点击“中断”按钮时也能够看就任务并没有当即中断运转(出格是假如呆板设置较低的话,提早的感到加倍分明),这些提早都是因为编译JSP页面招致的。编译好JSP页面以后,应对速率就要快多了。
5、实践使用
进度条不但使得用户界面加倍友爱,并且对服务器的功能也有优点,由于进度条会不休地告知用户以后的实行进度,用户不会再频仍地中断偏重新启动(革新)以后的义务。另外一方面,创立独自的线程来实行背景义务也会损耗很多资本,需要时可思索经由过程一个线程池来完成Thread对象的重用。别的,频仍地革新进度页面也增添了收集通讯开支,以是务必坚持进度页面简便短小。
在实践使用中,背景实行的沉重义务大概不同意中断,大概它不克不及供应具体的实行进度数据。比方,查找或更新干系数据库时,SQL命令实行时代不同意半途中断??不外假如用户暗示他想要中断或中断义务,程序能够在SQL命令实行终了后回退事件。
剖析XML文档的时分,我们没有举措获知已剖析内容准确的百分比。假如用DOM剖析XML文档,直到剖析完成后才失掉全部文档树;假如用SAX,固然能够晓得以后剖析的内容,但一般不克不及断定另有几内容必要剖析。在这些场所,义务的实行进度只能靠估量失掉。
估量一个义务必要几实行工夫一般是很坚苦的,由于它触及到很多要素,即便用实践测试的举措也没法失掉牢靠的结论,由于服务器的负载随时都在变更当中。一种复杂的举措是丈量义务每次实行所需工夫,然后依据最初几回实行的均匀工夫预算。
假如要进步估量工夫的准确度,应该思索完成一种针对使用特性的算法,综合思索多种要素,比方要实行的SQL语句范例、要剖析的XML形式的庞大水平,等等。
停止语:本文例子显现出用JSP、Java、HTML和JavaScript机关进度条是相称简单的,真正坚苦的是怎样将它用到实践使用当中,出格是取得背景义务的进度信息,但这个成绩没有通用的谜底,每种背景实行的义务都有它本人的特性,必需依照详细情形详细剖析。
学习JAVA的目的更多的是培养自身的工作能力,我觉得工作能力的一个核心就是:独立思考能力,因为只有独立思考后,才会有自己的见解 |
|