嘿我想实现一个Java Servlet,它只为每个用户启动一次线程。即使刷新它也不应该重新开始。我的最后一个方法给我带来了一些麻烦所以没有代码^^。有关servlet布局的任何建议吗?
public class LoaderServlet extends HttpServlet {
// The thread to load the needed information
private LoaderThread loader;
// The last.fm account
private String lfmaccount;
public LoaderServlet() {
super();
lfmaccount = "";
}
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
if (loader != null) {
response.setContentType("text/plain");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out = response.getWriter();
out.write(loader.getStatus());
out.flush();
out.close();
} else {
loader = new LoaderThread(lfmaccount);
loader.start();
request.getRequestDispatcher("WEB-INF/pages/loader.jsp").forward(
request, response);
}
}
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
if (lfmaccount.isEmpty()) {
lfmaccount = request.getSession().getAttribute("lfmUser")
.toString();
}
request.getRequestDispatcher("WEB-INF/pages/loader.jsp").forward(
request, response);
}
}
jsp使用ajax定期发布到servlet并获取状态。线程只运行3分钟,抓取一些last.fm数据。
答案 0 :(得分:1)
您需要的是Session listener。对于每个浏览器会话,方法sessionCreated()
仅被调用一次。因此,即使用户刷新页面,也不会出现问题。
然后,您可以继续为每个sessionCreated()
方法调用启动线程。
答案 1 :(得分:1)
实施javax.servlet.SingleThreadModel =>服务方法不会同时执行。 请参阅servlet规范。
答案 2 :(得分:0)
您的首要任务是弄清楚如何唯一地识别用户,例如,您如何识别代理/ SOHO网关背后的不同用户?
一旦你了解它,它基本上只是让一个单例对象为你的servlet服务用户< - >线程映射。
然后我们进入可扩展性问题,因为@ beny23在上面的评论中提到......我完全同意所提出的观点 - 你的方法不是合理的可扩展性!
干杯,
答案 3 :(得分:0)
据我了解,您希望避免并行处理来自同一用户的请求。我建议你采用其他方法:将锁定与每个用户关联并将其存储在会话中。在开始处理用户请求之前 - 尝试获取该锁定。因此当前线程将等待来自此用户的其他请求正在处理。 (在创建会话时使用会话侦听器存储锁定)
答案 4 :(得分:0)
假设可以通过创建Map<String,Thread>
来实现,然后调用servlet,它会尝试使用sessionId
查找地图。
只是草图:
public class LoaderServlet extends HttpServlet {
private Map<String,Thread> threadMap = new HashMap<>();
protected void doPost(..) {
String sessionId = request.getSesion().getId();
Thread u = null;
if(threadMap.containsKey()) {
u = threadMap.get(sessionId);
} else {
u = new Thread(...);
threadMap.put(sessionId, u);
}
// use thread 'u' as you wish
}
}
注意:
ThreadPools
,他们很棒