美文网首页
Servlet单实例多线程

Servlet单实例多线程

作者: lvlvforever | 来源:发表于2017-05-07 18:08 被阅读98次

1

Servlet容器为了提高响应速度,默认只允许同一个serlvet一个实例存在,对于多个请求使用多线程的方式来处理,避免了实例化servlet时的开销,当有请求到来时,servlet容器会从线程池中取一个空闲的线程,来处理请求,处理完毕后即放回线程池。
这样对于serlvet的实例变量在使用时需要注意下,实例变量并不是线程安全的,局部变量才是。下面看一个例子。

public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       private String message;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public TestServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        message = request.getParameter("message");
        String oldMessage = message;
        Thread cur = Thread.currentThread();
        System.err.println("当前threadId="+cur.getId()+" message="+message);
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.err.println("oldMesssage="+oldMessage+" message = "+message);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }

}

首先访问

http://127.0.0.1:8192/ServletTest/TestServlet?message=123

然后访问

http://127.0.0.1:8192/ServletTest/TestServlet?message=456

可以看到控制台输出:

当前threadId=20 message=123
当前threadId=21 message=456
oldMesssage=123 message = 456
oldMesssage=456 message = 456

分析结果可以得知,第二次访问时修改了实例变量message,导致最终第一次访问oldMessage和message不一致。
解决方法有三个:
1 使用Javax.servlet.SingleThreadModel
不过这个已经废弃了,不再多说。
2 去掉实例变量 使用局部变量。
3 使用同步 synchronized{}
第三种加锁非常影响性能,因此一般使用第二种方法。

相关文章

  • Servlet单实例多线程

    1 Servlet容器为了提高响应速度,默认只允许同一个serlvet一个实例存在,对于多个请求使用多线程的方式来...

  • 3.0.7 Servlet单例和线程安全问题

    Servlet实例是由Tomcat来创建的,因Tomcat只会创建一个Servlet实例,所以Servlet就是单...

  • 如何证明Servlet是单例的

    Servlet虽然基础,但是也经常会被问到,掌握其原理是很有必要的。 Servlet一般都是单例的,并且是多线程的...

  • Servlet 是线程安全的吗?

    概要 Servlet 默认是单例模式,在web 容器中只创建一个实例,所以多个线程同时访问servlet的时候,S...

  • 6月19日面试总结

    1、Servlet的生命周期 1.加载和实例化:Servlet容器负责加载和实例化Servlet。当Servlet...

  • java-web Servlet学习

    Servlet接口: Servlet主要方法: init()--ServletConfig servlet实例化后...

  • Servlet 实例

    Servlet 实例 Servlet 是服务 HTTP 请求并实现 javax.servlet.Servlet 接...

  • Servlet与Jsp(1)

    Servlet 实现原理Servlet接口使Servlet容器能将Servlet类载入内存,并在Servlet实例...

  • JSP基础(二)

    1.Servlet生命周期创建servlet实例当servlet实例化后,将调用这个对象的init()方法进行初始...

  • servlet常用调用方式

    servlet常用调用方式实例代码 测试servlet代码

网友评论

      本文标题:Servlet单实例多线程

      本文链接:https://www.haomeiwen.com/subject/kqxptxtx.html