行胜于言
图2中的时序图及步骤列表解释了这个设计的原理。

Figure 2. Sequence diagram of the Train pattern. Click on thumbnail to view full-sized image.
· TrainServlet实例化Job对象,发送Job对象到Dispatcher,然后暂停
· Dispatcher组合Job到批处理中。
· 对每一个批处理,Dispatche创建一个Worker类的实例。
· 在给定时间或批处理中包含一定数量的Job后,Worker生成SQL语句并与数据库交互。
· 每一个SQL语句执行批处理中与所有Job相关的任务。
· Worker中断TrainSevlet线程
· TrainSevlet下发结果给用户。
现在我们打算解剖一下这种设计的实际实现。
我们来看一下下面的servlet:
//TrainServlet.java
package train;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class TrainServlet extends HttpServlet {
int mEntryLength=250000;
Dispatcher mDispatcher;
Random mRand;
public void init() throws ServletException {
mRand = new Random(System.currentTimeMillis());
mDispatcher = new Dispatcher();
Thread ht = new Thread(mDispatcher); //Instantiate and execute in the separate thread.
ht.start();
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int id=0;
synchronized(mRand){
id=mRand.nextInt(mEntryLength);
}
Job job = new Job(String.valueOf(id)); //Each concurrent request creates job instance.
job.mJobThread = Thread.currentThread(); //Job should know the thread of the request.
PrintWriter out = response.getWriter(); //Job should know the output stream of the browser.
job.mOut = out;
mDispatcher.AddJob(job); //Job is sent to the dispatcher.
//Dispatcher is a container for all concurrent jobs.
try {
Thread.sleep(100000); //Let's wait until database interaction is finished.
System.out.println("Error: Request is timed out"); //Too bad. 100 seconds was not enough.
}
catch (InterruptedException ex2) {
//Success! Members of the Job instances are populated.
}
job.Marshall(); // Let's display the page in the browser.
}
}
新的servlet类似ClassicServlet,但有一些不同:用户请求被包含在Job类的实例中,与数据库的交互由Dispatcher类的实例来处理。
