Servlet线程安全

当服务器启动的时候,服务器的引擎就会创建一个Servlet的实例对象。系统只会创建一个直到服务区停止。每次请求都会开启一个新的线程进行处理,每次都会访问该对象的 service方法。当设计到共享资源的时候就会出现线程安全的问题。

/**
 * Servlet implementation class ServletDemo1
 */
public class ServletDemo1 extends HttpServlet {
    private static final long serialVersionUID = 1L;
    int  num=1;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            num++;
            try {
                Thread.sleep(6000);
            } catch (InterruptedException e) {
            }
            System.out.println(num);
            response.getWriter().append(num+"");
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

不同请求,不同线程都用到了 num 这个变量,所以会出现线程安全的问题。

解决办法1

/**
 * Servlet implementation class ServletDemo1
 */
public class ServletDemo1 extends HttpServlet {
    private static final long serialVersionUID = 1L
      int  num=1;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //同步鎖   锁住这个对象  当
        synchronized (this) {
            num++;
            try {
                Thread.sleep(6000);
            } catch (InterruptedException e) {
                 
            }
            System.out.println(num);
            response.getWriter().append(num+"");
        }
        
    }    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

加上锁就行了。当有人访问该对象的时候,锁住。执行完后进行释放次个锁,给别人用再 。就不会涉及到线程安全的问题了。

解决办法2

public class ServletThreadPoolDemo extends HttpServlet implements SingleThreadModel{
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         
        doGet(request, response);
    }
}

让 servlet去实现SingleThreadModel接口(标记性接口,不用实现任何东西) 就标注下次servlet 访问的方式是单线程的访问 ,不存在并发的现象了。但是次接口目前已经废除,不建议使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容