1、Servlet的线程安全
Servlet规范定义,在默认情况下(Servlet不是在分布式的环境中部署),Servlet容器对声明的每一个Servlet,只创建一个实例。 如果有多个客户请求同时访问这个Servlet,Servlet容器采用多线程,Servlet容器维护了一个线程池来服务请求。线程池实际上是等待执行代码的一组线程,这些线程叫做工作者线程(Worker Thread)。Servlet容器使用一个调度这线程(Dispatcher Thread)来管理工作者线程。当容器接受到一个访问Servlet的请求,调度者线程从线程池中选取一个工作者线程,将请求传递给该线程,然后由这个线程执行Servlet的service()方法
当这个线程正在执行的时候,容器收到了另一个请求,调度者线程将从池中选取另一个线程来服务新的请求。要注意的是,Servlet容器并不关心这个第二个 请求是访问同一个Servlet还是另一个Servlet。因此,如果容器同时收到访问同一个Servlet的多个请求,那么这个Servlet的 service方法将在多个线程中并发的执行。
由 于Servlet容器采用了单实例多线程的方式(这是Servlet容器默认的行为),最大限度地减少了产生Servlet实例的开销,显著地提升了对请 求的响应时间。对于Tomcat,可以在server.xml文件中通过<Connector>元素设置线程池中线程的数目。
2、属性的线程安全
在Servlet中,可以访问保存在ServletContext,HttpSession和ServletRequest对象中的属性。
① ServletContext中保存的属性可以被所有的Servlet访问,所以不是线程安全的。
② HttpSession对象只能在处理属于同一个Session的请求的线程中被访问,我们可以认为在一个时刻只有一个用户请求,因此,Session对 象的属性访问是线程安全的。然而实际情况并非如此,用户可以打开多个同属于一个进程的浏览器(比如IE浏览器中点击新建,新的窗口属于同一个 session,同一个进程),多个线程可以同时访问到Session对象的属性
③ServletRequest只在一个线程中被访问。因为只有一个线程服务请求,所有请求对象的属性访问是线程安全的。要注意的 是,ServletRequest对象是作为参数传进service方法中的,这个方法结束后,若仍然保存请求对象的引用,请求对象的行为将是不可预料 的。(Servlet本身就是多线程的,如果再在其中创建线程,将导致执行情况变得复杂,容易出现很多线程安全问题,所以设计系统时尽量不要采用在 Servlet中创建进程的方法)
谈到线程安全问题,会有人建议在多线程环境中使用集合类对象时使用同步的集合类,例如用Vector代替ArrayList,用Hashtable代替HashMap,这里我将拷贝论坛中同行给出的解释加深自己对同步的理解
vector是线程安全的,就如同一个房间,房门上有把锁,锁只有一个钥匙,当很多人想进房间,拿到那把能开锁的钥匙(姑且叫做A)才可以进入房间,而等到A退出房间并将钥匙随便给到在房门口等待的其他一人(姑且叫做B)的手上,B才可以进入房间,这样能保证房间里的资源在同一时间只被一个人占用。 arrayList不是线程安全的,就如同一个房门上没有锁的房间,因而所有的人都可以同时进入房间,房间里的资源在同一时间被多个人占用。这样在多线程中会出现问题。比如说那个资源是马桶,多个人进去抢那一个马桶势必大大出手形成竞争(race condition)。这样说不准没有一个人能正常如厕,所以arrayList在多线程里面用的话会很危险。 反过来看楼主的说法,楼主用多个线程来查看vector,然后再往vector里面添加数据。 if(vector.size() == 0){ Thread.sleep(100); vector.add(new Element()); } 我故意加了个Thread.sleep(); 这样会存在什么问题呢,多个线程都会看到vector的空间等于0,然后往vector里面添加元素。就如同多个人看到房间里面的马桶一次都没有用过,于是都想用第一次,然后他们该怎么做呢?排队拿钥匙进入房间用马桶。于是马桶被用了3次。 而如果在这里是arrayList会是什么情况呢?所有的人都进去用,有可能马桶只被用了1次(arrayList里面只存用一个元素)。那为什么明明3个人用过马桶,最后却只被用了一次呢,这个与试试矛盾啊,这就是因为房门没有锁,3个人有可能同时共用了一次马桶,这个与事实想违背,所以说arrayList是不安全的。 那么楼主说vector也是不安全的 因为上面的一段代码,这段代码就好比是房间(1)外面有一个更大的房间(2),房间(2)的房门没有锁,所以所有的人都可以进入房间(2)来看,这样房间(2)是不安全的,不安全的原因是楼主没把房间上锁,但是房间(2)不安全并不代表房间(1)不是安全的。
总而言之,要想做到真正的线程安全,还是需要程序员根据具体问题在应用层设计自己的解决方案,而不能单纯的依靠某些提供的“同步”Java类
相关推荐
Servlet容器模型的另一个关键特性是多线程模型。由于HTTP请求是无状态的,Servlet容器通常为每个请求创建一个新的线程来调用Servlet的`service()`方法,以提高并发性能。这意味着Servlet必须是线程安全的,避免在多...
### servlet多线程详解 #### 一、Servlet容器如何同时处理多个请求 Servlet容器通过采用多线程机制来实现对多个请求的同时处理。这一过程主要依赖于容器内部维护的一个线程池,它由一系列处于待命状态的工作线程...
它基于Servlet和JSP规范,对于处理HTTP请求,Tomcat采用了多线程模型来提升性能。在这个主题中,我们将深入探讨"Tomcat中多线程对于Servlet处理"的相关知识点,特别关注在5.5.17版本中的实现。 1. **Tomcat的线程...
同时包含系统通用多线程模型与消息通讯、多对多关系的分布式锁、基于Servlet的HTTP框架、基于系统通用多线程模型的Websocket框架、支持行级锁的多线程锁等组件,按需选择组件,不绑架开发者。.zip,grain是一个极简的...
这使得Servlet天然支持多线程模型,能够处理大量并发请求,提高系统性能。 二、多线程在Servlet中的应用 1. 请求处理:每个用户的HTTP请求被分配到独立的线程,这样可以避免一个请求阻塞其他请求,提高了服务器的...
Servlet和Struts Action是两种常见的Java Web开发组件,它们在多线程环境下运行时可能存在线程安全问题。线程安全是指在多线程环境中,一个类或者方法能够正确处理多个线程的并发访问,保证数据的一致性和完整性。 ...
- Web容器(如Tomcat、Jetty)在Servlet多线程模型中扮演关键角色,它负责创建和管理线程,调度Servlet的执行,以及处理线程同步等问题。 至于提供的文件"8点25分平安大厦集合旅游人员名单.xls",虽然与Servlet多...
Servlet线程同步计数器实验是Java Web开发中一个重要的实践课题,主要涉及到Servlet容器如何处理并发请求以及如何确保在多线程环境下的数据一致性。在这个实验中,我们将深入理解Servlet生命周期、线程模型以及线程...
由于Servlet是单例模式实现的,这意味着每次请求都会复用同一个Servlet实例,因此,在多线程环境下,如何确保Servlet的线程安全就显得尤为重要。 #### 二、解决Servlet线程安全问题的方法 针对Servlet线程安全问题...
然而,Servlet在多线程环境下的线程安全问题是一个不容忽视的话题。在Servlet的生命周期中,Tomcat容器会根据需求实例化Servlet并管理其生命周期。当第一个请求到达时,Tomcat会创建Servlet实例,后续的请求将复用同...
Servlet作为Java服务器端组件,其默认的多线程模型使得一个Servlet实例可能会被多个客户端请求同时调用,这就要求开发者对线程安全有深入的理解,以避免潜在的数据不一致性和其他并发问题。 Servlet的多线程机制...
它的一个显著特点是支持多线程处理能力,这使得Servlet在面对大量并发请求时仍能保持高性能。然而,这种多线程特性同时也带来了线程安全性的问题,特别是当Servlet中的实例变量被多个线程共享时。本文旨在深入探讨...
Servlet的多线程模型允许它同时处理多个客户端请求,提高了Web应用的并发处理能力。在编写Servlet时,开发者需要注意线程安全问题,确保共享资源的正确访问。 3. **Struts**:Struts是一个基于MVC(Model-View-...
2. **Servlet容器的多线程模型**: - Tomcat使用了Coyote Connector来处理HTTP请求,它使用了工作线程模型。每当有新的请求到达,工作线程就会从连接器的队列中取出请求,并调用Servlet的`service`方法。通过这种...
- **单线程模型和多线程模型**:Servlet可以配置为每个请求创建一个新的Servlet实例(单线程模型),或者所有请求共享同一个Servlet实例(多线程模型)。单线程模型更安全,但效率较低;多线程模型则相反。 4. **...
Servlet容器默认支持多线程模型,这意味着同一个Servlet实例可以同时处理多个请求。然而,某些情况下可能需要限制Servlet仅在一个线程中运行,这被称为单线程模型。 - **多线程模型**:提高了Servlet处理请求的效率...
- 多线程还可以简化模型的构建,使得程序设计更加模块化,易于管理和维护。 - 实现异步或后台处理任务,可以提高应用程序对事件的响应速度,实现更加流畅的用户交互。 3. 线程通信与数据交换 - 当多个线程需要...
- 多线程模型:为了提高性能,可以通过多线程处理请求,但需要确保线程安全。 - 异步Servlet:Java 7引入了异步Servlet,允许Servlet在处理请求期间释放线程,进行其他工作。 4. **Servlet上下文**: - ...