线程安全java servlet
我需要知道以下代码在线程方面是否存在任何问题。我一直认为,只要不使用类级变量,线程就不是问题线程安全java servlet,java,servlets,multithreading,Java,Servlets,Multithreading,我需要知道以下代码在线程方面是否存在任何问题。我一直认为,只要不使用类级变量,线程就不是问题 public class UploadReferralImage extends HttpServlet { String CLASS_NAME = "UploadReferralImage"; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
public class UploadReferralImage extends HttpServlet
{
String CLASS_NAME = "UploadReferralImage";
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// Not handling Get, service must be invoked via Post.
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String METHOD_NAME = "doPost";
LogHelper.debug(PACKAGE_NAME, CLASS_NAME, METHOD_NAME, "Made it to the servlet");
String reply = upload(request);
response.setHeader("Content-Type", "text/xml");
response.getWriter().write(reply);
response.getWriter().flush();
response.getWriter().close();
}
public String upload(HttpServletRequest request)
{
String METHOD_NAME = "upload";
LogHelper.debug(PACKAGE_NAME, CLASS_NAME, METHOD_NAME, "Inside upload");
String replyMsg = "Unable to call ImageUpload";
try
{
ObjectInputStream inputFromApplet = new ObjectInputStream(request.getInputStream());
FileBean fBean = (FileBean) inputFromApplet.readObject();
inputFromApplet.close();
LogHelper.debug(PACKAGE_NAME, CLASS_NAME, METHOD_NAME, fBean.getFileName());
replyMsg = doImageUpload(fBean);
}
catch (IOException e)
{
e.printStackTrace();
replyMsg = "Exception :" + e.toString();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
replyMsg = "Exception :" + e.toString();
}
return replyMsg;
}
private String doImageUpload(FileBean fBean)
{
//Save the file and return the response
SaveCaseClientAgent saveCaseClientAgent = new SaveCaseClientAgent();
saveCaseClientAgent.save(fBean);
}
你说得对
只要您不使用类级变量,您的Servlet
将是线程安全的
为了安全起见,不妨将您的班级级别设置为String
final
:
final String CLASS_NAME = "UploadReferralImage";
通常,servlet容器中只有一个servlet实例一次可重入地服务多个请求。因此,由于竞争条件,使用实例变量将对象从一个方法传递到另一个方法是baad的想法 解决这个问题的最好(也是最简单)方法是编写自己的“处理程序”类,每个请求实例化一次,然后将所有内容传递给它。在代码中,它看起来是这样的:
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
new MyHandler().doGet(req, resp);
}
现在在
MyHandler
中,重用实例变量是非常安全的 看起来不错。你有理由相信它不是吗?我只是担心上传方法是公开的,不知道我为什么这么做,我必须纠正它。但是到目前为止还没有问题。所以我通过传递public void doGet(HttpServletRequest req,HttpServletResponse resp){upload(request);}的方式可能会导致问题?不。在您的情况下,两个不同的请求之间没有共享状态(线程之间不共享调用堆栈,传递给方法的引用通过堆栈共享)。这说明我的“技巧”仍然是一个更干净、更广泛使用的解决方案。