`
wade6
  • 浏览: 274194 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

【实际问题】Servlet单实例多线程的线程安全问题

 
阅读更多

涉及的关键字:JVM、堆、栈、线程、局部变量、对象变量、互斥锁

 

问题出处:http://www.iteye.com/topic/225749

 

一般servlet在jvm中只有一个对象,当有多个请求过来的时候,相当于多个线程来执行这个servlet。

 

例如下面的servlet

 

 

public class HelloServlet extends HttpServlet {  
    private int j =0;  
    public void doPost(HttpServletRequest request, HttpServletResponse response){  
        int i=0;  
        i++;  
        j++;  
        //这里的i和j那个是线程安全的那个不是呢,后面我们将从线程的堆栈,和jvm的堆的概念来解释这个问题  
//request 和 response  对象是不是线程安全的  
   }  
}  

 

 

       JVM是基于栈的虚拟机.JVM为每个新创建的线程都分配一个栈.也就是说,对于一个Java程序来说,它的运行就是通过对栈的操作来完成的。栈以帧为单位保存线程的状态。JVM对栈只进行两种操作:以帧为单位的压栈和出栈操作。

 

        我们知道,某个线程正在执行的方法称为此线程的当前方法.我们可能不知道,当前方法使用的帧称为当前帧。当线程激活一个Java方法,JVM就会在线程的Java栈里新压入一个帧。这个帧自然成为了当前帧.在此方法执行期间,这个帧将用来保存参数,局部变量,中间计算过程和其他数据.这个帧在这里和编译原理中的活动纪录的概念是差不多的。

 

 

这里还要补充一下堆的概念:

 

        堆(heap)是放实例和数组的,JAVA里面没有全局变量这个概念,所有变量都是以类的属性或者参数等形式存在的。

        但是数组和类的引用是放在栈中。

 

       学过汇编的可能都知道,数据是是存储在栈内的,执行的代码逻辑是可以共用的。当多个线程来访问同一个方法的时候,共享同一段代码逻辑,但是方法对应的数据是存储在各自的栈(stack)中,如局部变量和参数还有对象的引用(局部变量和参数也可能是对象的引用)。所以多线程并发的情况下,出现不同步的现象主要是因为各自栈存放的某些数据是共享的,说白了就是同一个数据的引用(不是copy)被存放在不同的栈中。 例如类X的对象A被多个线程访问,他的引用被保存在多个线程的栈中,当多个线程访问A对象的某个属性b的时候如果不加锁就会出现不同步的现象。所以为了避免这种情况发生一是加锁,二就是为每个线程都生成一个类X的对象,这样每个线程的栈中存放的类X引用所对应的堆中的对象都不一样,当然就不存在共享的问题。

 

 

 

       现在我们回到开始那个例子,可以很好的分析出参数request,respone,i是线程安全的,而j是线程不安全的;

 

       为什么?

       request,respone是线程安全的是因为每个线程对应的request,respone对象都是不一样的,不存在共享问题。

 

       i是线程安全的是应为i是局部变量,每个线程的栈中存放的值也是各自独立的。

 

       j线程不安全是应为它是类HelloServlet的属性,找了很多资料都不能说清楚它到底放在那里,从实际效果来看,它是不安全的,所以应该是放在和类对象一起放在堆里面的,堆里面估计是复制了一份过来,因为HelloServlet对多个线程而言只有

一个实例,所以存在共享问题。

 

分享到:
评论

相关推荐

    servlet线程安全问题

    Servlet 线程安全问题是指在使用 Servlet 编程时,如果不注意多线程安全性问题,可能会导致难以发现的错误。Servlet/JSP 技术由于其多线程运行而具有很高的执行效率,但这也意味着需要非常细致地考虑多线程的安全性...

    servlet与Struts action线程安全问题分析

    Servlet和Struts Action是两种常见的Java Web开发组件,它们在多线程环境下运行时可能存在线程安全问题。线程安全是指在多线程环境中,一个类或者方法能够正确处理多个线程的并发访问,保证数据的一致性和完整性。 ...

    servlet多线程

    Servlet容器默认采用单实例多线程的方式处理请求,这意味着对于每个Servlet类,容器只会创建一个实例,并让这个实例服务于所有针对该Servlet的请求。这种方式减少了创建Servlet实例的开销,显著提升了系统性能,尤其...

    Web-Servlet_多线程_

    1. 线程安全:由于Servlet实例可能被多个线程共享,因此需要注意线程安全问题。避免在Servlet实例中使用非线程安全的数据结构,如ArrayList,应使用ConcurrentHashMap等线程安全的集合类。此外,使用synchronized...

    servlet与Struts action线程安全问题分析(pdf)

    然而,这种多线程特性同时也带来了一定程度上的线程安全问题。本文将深入探讨Servlet及其衍生框架Struts中的线程安全问题,并提出相应的解决方案。 #### 二、Servlet的多线程机制 Servlet的生命周期是由Web容器...

    Servlet线程安全问题.docx

    然而,Servlet在多线程环境下的线程安全问题是一个不容忽视的话题。在Servlet的生命周期中,Tomcat容器会根据需求实例化Servlet并管理其生命周期。当第一个请求到达时,Tomcat会创建Servlet实例,后续的请求将复用同...

    深入研究Servlet线程安全性问题.pdf

    这意味着多个线程可能会同时访问同一个Servlet实例,因此需要特别注意线程安全性问题。 #### 三、Servlet线程安全问题分析 线程安全问题是由于Servlet中实例变量的使用不当导致的。在多线程环境中,如果多个线程...

    深入研究Servlet线程安全性问题

    Servlet作为Java服务器端组件,其默认的多线程模型使得一个Servlet实例可能会被多个客户端请求同时调用,这就要求开发者对线程安全有深入的理解,以避免潜在的数据不一致性和其他并发问题。 Servlet的多线程机制...

    1工作临时-servlet 多线程问题

    标题中的“1工作临时-servlet 多线程问题”表明我们即将探讨的是在实际工作中遇到的一个与Servlet和多线程相关的技术难题。Servlet是Java Web开发中用于处理HTTP请求的服务端组件,而多线程则涉及到并发编程,是...

    Servlet线程安全的解决方法

    由于Servlet是单例模式实现的,这意味着每次请求都会复用同一个Servlet实例,因此,在多线程环境下,如何确保Servlet的线程安全就显得尤为重要。 #### 二、解决Servlet线程安全问题的方法 针对Servlet线程安全问题...

    Servlet是线程不安全的1

    Servlet是一种线程不安全的组件,它的线程不安全性体现在多线程环境下共享一个实例变量,导致线程安全问题。下面我们将从Servlet的工作原理说起,详细解释Servlet接收和响应客户请求的过程,并探讨Servlet线程不安全...

    tomcat中多线程对于servlet处理的4篇资料

    在Java Web开发中,Tomcat是一个广泛...综上所述,理解Tomcat中的多线程处理对于优化Servlet性能和解决潜在的并发问题至关重要。通过对线程池的配置和使用最佳实践,开发者可以有效地提高Web应用的响应速度和可伸缩性。

    Servlet线程同步计数器实验

    这意味着在高并发场景下,Servlet实例可能会被多个线程同时访问,如果没有正确处理,就可能导致数据不一致的问题。 线程同步是解决这类问题的关键。在Java中,我们可以使用synchronized关键字、Lock接口(如...

Global site tag (gtag.js) - Google Analytics