我的servlet上有一个ajax方法,可以同时为同一个用户运行。很抱歉,如果我使用错误的词语来描述问题,但到目前为止我是如何理解它的(不太了解线程)。
无论如何这是方法
private void ajaxPartidas() throws ServletException, IOException {
//Variables necesarias
DataSource pool = (DataSource) session.get().getAttribute("pool");
Recibo registro = null;
int id = -1;
try{ id = Integer.parseInt(request.get().getParameter("id"));}catch(NumberFormatException e){}
if(id > 0){
registro = new Recibo(id);
if(!registro.obtener(pool))
registro = null;
registro.setPartidas(Partida.obtenerRegistros(pool, registro.getId()));
}
response.get().setContentType("application/json");
response.get().setHeader("Content-Type", "application/json; charset=utf-8");
response.get().getWriter().print((new Gson()).toJson(registro.getPartidas()));
}
这个方法是通过ajax调用的,它在第一次被调用时工作正常,但第二次(在相同的id上)并且它在getWriter()行返回一个NullPointer。我环顾四周,每个人似乎都在向线程指出问题。现在,每次servlet进入
时都会有更多的上下文doPost(request, response)
我在全局变量中分配了一个如此声明的threadlocal变量
private static ThreadLocal<HttpServletResponse> response = new ThreadLocal<>();
我为其指定了回复
Home.response.set(response);
在doPost()方法中。
我如何制作getWriter()线程安全?
答案 0 :(得分:1)
不确定为什么要将响应分配给班级ThreadLocal
?每个新用户生成的请求都有一个干净的request
和response
对象。只要遵循使用Java Servlet的正确准则,getWriter
和servlet类上的所有方法都是线程安全的。 Java Servlets的一般规则是,只要不使用类级变量,就是线程安全的。
您需要将请求和响应对象作为参数传递给ThreadLocal
方法,然后像往常一样调用它,而不是使用ajaxPartidas
。因此,您的doPost
方法看起来像这样
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ajaxPartidas(request, response);
}
并发问题已由Servlet类本身处理,您只需要编写业务逻辑。有关使用带有Ajax的Java Servlet的更多详细信息,请参阅类似线程中的此答案:https://stackoverflow.com/a/4113258/772385
答案 1 :(得分:0)
Tomcat为每个用户请求创建一个新的请求和响应。所以它们已经是线程安全的(除非你进入并创建一个新的线程)。此外,请确保您传递“id”并正确设置。我认为这是与getWriter()在同一行上的“registro”对象导致NullPointerException。