Servlet 并发加锁

2019-03-20  本文已影响0人  旦暮何枯

servlet 处理实现机制

当有线程执行完毕,返回线程池
当线程池中的所有线程都在执行服务,新来的请求排队
当超过了设置的最大排队数量的请求到来时,容器会拒绝处理新的请求

线程模型

线程模型.png

总结特点

线程安全

变量线程安全
属性的线程安全
避免在 Servlet 中创建线程

servlet 本身就是在多线程中进行处理的,在 servlet 中再创建线程;会造成运行情况复杂,更容易发生多线程安全问题。

多个 Servlet 访问外部对象加锁

使用 synchronized 同步块进行加锁操作

  1. 创建一个 maven web-app
  2. 创建一个 SynchronizedTest 的 servlet 类
  3. 在 servlet 类中的 doGet 方法中使用 synchronized 标识进行加锁
  4. 在部署描述符中注册

SynchronizedServlet 类

public class SynchronizedServlet extends javax.servlet.http.HttpServlet {

    String name; // 为引入线程不安全问题引入实例变量,不推荐使用实例变量
    @Override
    public void init() throws ServletException {
        super.init();
    }

    @Override
    public void destroy() {
        super.destroy();
    }

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        //使用 synchronized 标识进行代码加锁
        synchronized (this) {
            name = request.getParameter("username");//从 url 中获取 username 的值
            PrintWriter printWriter = response.getWriter();  // 创建 PrintWriter 对象,在页面中打印
            try {
                //为模拟大量并发 设置线程休眠时间。
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            printWriter.print("username: " + name);
        }
    }
}

『项目目录』:https://github.com/wengfe/JAVA/tree/master/SynchronizedTest/src/main

上一篇下一篇

猜你喜欢

热点阅读