servlet单实例多线程模式的理解

文章探讨了servlet的生命周期,说明了单实例多线程的原理及优点,如节省内存和提高响应速度。然而,这也带来了线程安全问题,主要体现在数据并发访问时的不安全性。为了解决这个问题,文章提到了Java内存模型、线程池、ThreadLocal、数据库锁以及事务管理等策略,强调了业务逻辑和并发控制的重要性。
摘要由CSDN通过智能技术生成

servlet单实例多线程分析

servlet的生命周期由web容器负责,以tomcat作为服务器时,servlet作为组件交给tomcat管理。当浏览器客户端第一次发送请求到服务器端的时候,tomcat会创建一个全新的servlet实例来处理该请求,并创建一个新的线程,当客户端再次发送相同的请求的时候,便不会再实例化该servlet,而是创建一个新的线程,来访问该servlet。这是servlet单实例多线程的原理。

单实例的好处是:减少了servlet实例的消耗,有利于节省内存,节约资源,在客户端频繁访问服务器的时候,加快了服务器的响应速度。

多线程可能会造成的问题:线程安全问题,当多个线程同时访问一个servlet的时候,并且访问同一个资源的时候,可能会对数据造成不安全的影响。

处理多线程并发的安全问题

多线程机制

当tomcat容器启动时,servlet就被加载实例化到容器中。容器初始化时servlet读取配置文件,加载到配置文件中的线程池中设置的线程数目,存放在线程池中。当客户端有请求达到servlet时,servlet通过调度线程调度该线程池中等待执行的工作线程给当前请求,并处理其相应内容,请求结束后,工作线程又被放回线程池中。

Java内存模型对多线程的处理

在Java内存模型(JMM)中,系统存在每个程序的一个主内存,所有的变量存储在主内存中,每个线程中会有主内存中的共享变量的副本,该线程可以操作共享变量的副本。而在各自的线程中,对主内存是不可见的,每个线程的数据不是立即写回内存,JMM中存在一个缓存区,会对数据进行缓存。在每个线程中的局部变量和其他线程之前也是互不干扰的。

Java代码层面解决方法
  1. 在servlet中不使用实例变量,可以将变量写在各自的方法内,使用局部变量。

  1. 实现 SingleThreadModel 接口或在同步代码块使用synchronized,但是这两种方法对内存的消耗过高,不利于性能。

  1. @Transactional注解,可设置四种事务隔离级别,解决事务的原子性问题,当事务出错的时候,可以回滚事务,避免数据操作错误。

  1. JUC并发处理。

  1. ThreadLocal可以为当前线程开辟一个新的空间,用于存放临时数据,但只对当前服务器可见,其他服务器无法访问。

  1. 业务层代码逻辑控制。

数据库层面解决问题
  1. 数据库设置访问权限。

  1. 利用数据库的锁机制,读写锁对数据进行控制。

  1. 数据库MVCC锁实现多版本并发控制。

多线程并发情况举例

同一用户同时请求访问同一个资源
  1. 避免用户在多个地方登录,先做登录校验。

  1. 业务层代码逻辑判断当前资源是否合理存在。

不同用户同时请求访问同一个资源

JUC并发处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值