文档章节

java servlet拾遗(3)-servlet 线程安全问题

haoran_10
 haoran_10
发布于 2016/07/15 16:36
字数 535
阅读 33
收藏 1

精选30+云产品,助力企业轻松上云!>>>

Servlet容器启动时,会对每一个Servlet对象实例化一次,而且是仅仅一次,在运行的时候,不管多少个请求都是同时执行这一个Servlet对象实例。 也就是说Servlet对象是单实例多线程,这个时候,就需要注意到并发安全问题。

 

一、为什么不安全

    先看两个定义:

  • 实例变量:实例变量在类中定义。类的每一个实例都拥有自己的实例变量,如果多个线程同时访问该实例的方法,而该方法又使用到实例变量,那么这些线程同时访问的是同一个实例变量,会共享该实例变量。
  • 局部变量:局部变量在方法中定义。每当一个线程访问局部变量所在的方法时,在线程的堆栈中就会创建这个局部变量,线程执行完这个方法时,该局部变量就被销毁。所有多个线程同时访问该方法时,每个线程都有自己的局部变量,不会共享。

例如:

public class MyServlet extends HttpServlet{
 private static final long serialVersionUID = 1L;
 
 private String userName1 = null;//实例变量
 
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
         throws ServletException, IOException{
  userName1 = req.getParameter("userName1");
 
  String userName2 = req.getParameter("userName2");//局部变量
 
  //TODO 其他处理
 }
}

userName1则是共享变量,多个线程会同时访问该变量,是线程不安全的。

userName2是局部变量,不管多少个线程同时访问,都是线程安全的。

 

二、怎么解决

  • 如果不涉及到全局共享变量,全部放到局部变量,最好的做法
  • 如果使用到全局共享的场景,可以使用加锁的方式,比如
public class MyServlet extends HttpServlet{
 private static final long serialVersionUID = 1L;
 
 private String userName1 = null;//实例变量
 
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
         throws ServletException, IOException{
  synchronized (userName1) {
   userName1 = req.getParameter("userName1");
   //TODO
  }
 
 
  String userName2 = req.getParameter("userName2");//局部变量
 
  //TODO 其他处理
 }
}

或者使用线程安全的StringBuffer去代替String,

或者使用线程安全的容器比如:   java.util.concurrent.ConcurrentHashMap 等等

最好使用乐观锁的形式去加锁

 

haoran_10
粉丝 27
博文 89
码字总数 82446
作品 0
杭州
程序员
私信 提问
加载中
请先登录后再评论。
【转载】Java Web学习(五)——Servlet开发(一)

一、Servlet简介   Servlet是sun公司提供的一门用于开发动态web资源的技术。   Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数...

osc_y40tpu41
2019/10/20
2
0
javaweb Servlet开发

一、Servlet简介   Servlet是sun公司提供的一门用于开发动态web资源的技术。   Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数...

木云凌
2018/10/25
138
0
javaweb学习总结(五)——Servlet开发(一)

javaweb学习总结(五)——Servlet开发(一) 一、Servlet简介   Servlet是sun公司提供的一门用于开发动态web资源的技术。   Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态w...

osc_lqlcgocs
2018/08/17
2
0
JavaWeb学习总结(三):Servlet开发(一)

一、Servlet简介   Servlet是sun公司提供的一门用于开发动态web资源的技术。   Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数...

osc_axql7nqi
2018/12/22
16
0
JavaWeb学习笔记12--Servlet开发(一)

一、Servlet简介   Servlet是sun公司提供的一门用于开发动态web资源的技术。   Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数...

osc_mtv7lwgr
2018/05/06
1
0

没有更多内容

加载失败,请刷新页面

加载更多

我在哪里可以在线找到Android源代码? [关闭] - Where can I find Android source code online? [closed]

问题: Particularly, where can I browse the source code for any android source application(egthe contact application) ? 特别是,我在哪里可以浏览任何Android源应用程序(例如联系人......

javail
26分钟前
17
0
如何以常规格式打印日期? - How to print a date in a regular format?

问题: This is my code: 这是我的代码: import datetimetoday = datetime.date.today()print today This prints: 2008-11-22 which is exactly what I want. 打印: 2008-11-22这正是我......

fyin1314
56分钟前
17
0
动态规划:LC198.打家劫舍

题目描述: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入...

曦鱼violet
今天
30
0
OSChina 周一乱弹 —— 南方水到底多深

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @薛定谔的兄弟 :分享洛神有语创建的歌单「我喜欢的音乐」: Various Artists-用印度乐器演奏苏联国歌(洛天侬 remix) 手机党少年们想听歌,请...

小小编辑
今天
56
0
快递100云平台的安全措施--API限流

2、热点参数限流 注意: 若 entry 的时候传入了热点参数,那么 exit 的时候也一定要带上对应的参数(exit(count, args)),否则可能会有统计错误。 3、通过 ParamFlowRuleManager 的 loadRu...

bykk
今天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部