Servlet中多线程并发问题

问题描述:
在开发小型学生在线测试系统时,采用JavaWeb(基于Servlet类),在实际测试过程中,出现了a学生考试提交后页面出现了b学生的基本信息,通过多次google,发现是由于Servlet单实例多线程导致,现将分析结果总结如下:
Servlet的多线程机制
首先了解一下Servlet的多线程机制,Servlet体系结构是建立在Java多线程机制之上的。当某客户初次请求Servlet时,Servlet容器会根据其配置文件(web.xml)实例化Servlet类。当有其他新的客户请求该Servlet时,Servlet容器将不会再实例化这个Servlet类,而是开辟一个新的线程,所以出现了单实例多线程状态。
问题解析:所以当a学生访问Servlet时,程序会正常的运行,当多个用户并发访问时,就会出现其他用户的信息显示在另外一些用户的浏览器上的问题。
首先关心一下内存机制:
Java的内存模型JMM主要是为了规定了线程和内存之间的一些关系。根据JMM的设计,系统存在一个主内存,Java中所有实例变量都存储在主存中,对于所有的线程都是共享的,每条线程都有自己的工作内存,工作内存由缓存和堆栈两部分组成,缓存中保存的是主存中变量的拷贝,缓存可能并不总和主存同步,也就是缓存中变量的修改可能没有立刻写到主存中;堆栈保存的线程的局部变量,线程之间无法相互直接访问堆栈中的变量。
解决方法:
查阅网上的解决方案,总结为三
1.实现 SingleThreadModel 接口
该接口指定了系统如何处理对同一个Servlet的调用。如果一个Servlet被这个接口指定,那么在这个Servlet中的service方法将不会有两个线程被同时执行,当然也就不存在线程安全的问题。只要继承这个接口就行。
缺点:
为每个请求开启一个新的实例, 系统的开销比较大,在Servlet2.4以后已被抛弃。
2.同步对共享数据的操作
使用synchronized 关键字能保证一次只有一个线程可以访问被保护的区段,在本论文中可以通过同步块操作来保证Servlet的线程安全。
缺点:
因为被同步的代码块在同一时刻只能有一个线程执行它,使得其同时处理客户请求的吞吐量降低,而且很多客户处于阻塞状态。另外为保证主存内容和线程的工作内存中的数据的一致性,要频繁地刷新缓存,这也会大大地影响系统的性能。所以在实际的开发中也应避免或最小化Servlet 中的同步代码。
3.避免使用实例变量(推荐)
临时变量存储在栈,每个线程有自己的栈空间。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值