serverlet线程安全吗

本文属于转载:http://www.cnblogs.com/itTeacher/archive/2012/11/14/2769822.html

这个问题,在网上没有看到一个确切的答案,所以我们来分析一下:
首先什么是线程安全?
引用概念:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

那么我们都知道servlet是多线程的,同时一个servlet实现类只会有一个实例对象,也就是它是Singleton的,所以多个线程是可能会访问同一个servlet实例对象的。

每个线程都会为数据实例对象开辟单独的引用,那么servlet会是线程安全的吗?

要判断是否是线程安全,我们需要知道线程安全问题是由什么引起的。
搜索得到答案:线程安全问题都是由全局变量及静态变量引起的。
看到这个答案,突然想起很多年前调查过的一个bug, 那时我们系统中遗留的代码中写了很多全局变量,有一次发布后,客户反馈,当有多人同时进行某个操作时,我们的数据出了问题,那时我们调查后的结果就是:多人同步操作时,有些全局变量的值不对了,之后我们专门设一个人花了很多工夫来将所有全局变量都改成了局部变量了,并且项目要求以后不允许用全局变量。原来那时侯我就已经碰到过线程不安全的情况了啊,不过处理方式或者不用全局,或者加入同步,若加入同步同时也要考虑一下对程序效率会不会产生影响。

由此可知,servlet是否线程安全是由它的实现来决定的,如果它内部的属性或方法会被多个线程改变,它就是线程不安全的,反之,就是线程安全的。

在网上找到一个例子,如下:

public class TestServlet extends HttpServlet {
     private int count = 0;  
      
     @Override
     protected void service(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         response.getWriter().println("<HTML><BODY>");
         response.getWriter().println(this + " ==> ");
         response.getWriter().println(Thread.currentThread() + ": <br>");
         for(int i=0;i<5;i++){
             response.getWriter().println("count = " + count + "<BR>");
             try {
                 Thread.sleep(1000);  
                 count++;  
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
         response.getWriter().println("</BODY></HTML>");
     }
 }



当同时打开多个浏览器,输入http://localhost:8080/ServletTest/TestServlet时,他们显示的结果不同,这就说明了对于属性count来说,它是线程不安全的,
为了解决这个问题,将代码重构,如下:

public class TestServlet extends HttpServlet {
      private int count = 0;  
      private String synchronizeStr = "";
      @Override
     protected void service(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         response.getWriter().println("<HTML><BODY>");
         response.getWriter().println(this + " ==> ");
         response.getWriter().println(Thread.currentThread() + ": <br>");
         synchronized (synchronizeStr){
             for(int i=0;i<5;i++){
                 response.getWriter().println("count = " + count + "<BR>");
                 try {
                     Thread.sleep(1000);  
                     count++;  
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
             }
         }
         response.getWriter().println("</BODY></HTML>");
     }
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当面试中涉及到Servlet的问题时,以下是一些常见的问题和示例答案供参考: 1. 什么是Servlet? ServletJava编写的服务器端程序,用于处理HTTP请求和生成HTTP响应。它运行在Web容器中,如Tomcat或Jetty。 2. Servlet的生命周期是什么? Servlet的生命周期包括以下三个阶段: - 初始化阶段:通过调用init()方法进行初始化,可以在此阶段执行任何必要的配置。 - 服务阶段:每次接收到HTTP请求时,都会调用service()方法来处理请求,并生成相应的HTTP响应。 - 销毁阶段:通过调用destroy()方法来终止Servlet的运行,并释放相关资源。 3. Servlet和JSP之间有什么区别? Servlet和JSP都是用于构建动态Web应用程序的技术,但它们有以下区别: - ServletJava类,完全由Java代码编写,而JSP是基于HTML的,其中嵌入了Java代码。 - ServletJava代码中处理请求和生成响应,而JSP使用标签和表达式在HTML中嵌入Java代码。 - Servlet更适合处理业务逻辑和数据访问,而JSP更适合用于呈现动态内容。 4. 如何在Servlet中处理GET和POST请求? 在Servlet中,可以通过重写doGet()和doPost()方法来处理GET和POST请求。例如: ```java protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 处理GET请求的代码 } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 处理POST请求的代码 } ``` 5. Servlet中如何获取请求参数? 可以使用HttpServletRequest对象的getParameter()方法来获取请求参数。例如: ```java String username = request.getParameter("username"); String password = request.getParameter("password"); ``` 这些问题只是Servlet面试中的一部分,根据面试的深度和要求,可能会涉及更多的问题。希望这些示例能对你有所帮助!如果你有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值