Race Condition: Singleton Member Field 竞争条件:单例的成员字段

Abstract

Servlet 成员字段可能允许一个用户查看其他用户的数据。

Explanation

许多 Servlet 开发人员都不了解 Servlet 为单例模式。 Servlet 只有一个实例,并通过使用和重复使用该单个实例来处理需要由不同线程同时处理的多个请求。 这种误解的共同后果是,开发者使用 Servlet 成员字段的这种方式会导致某个用户可能在无意中看到其他用户的数据。 换言之,即把用户数据存储在 Servlet 成员字段中会引发数据访问的 race condition。

例 1: 以下 Servlet 把请求参数值存储在成员字段中,然后将参数值返回给响应输出流。

public class GuestBook extends HttpServlet {
String name;
protected void doPost (HttpServletRequest req,
HttpServletResponse res) {
name = req.getParameter("name");
...
out.println(name + ", thanks for visiting!");
}
}

当该代码在单一用户环境中正常运行时,如果有两个用户几乎同时访问 Servlet,可能会导致这两个请求以如下方式处理线程的插入:

线程 1: assign "Dick" to name

线程 2: assign "Jane" to name

线程 1: print "Jane, thanks for visiting!"

线程 2: print "Jane, thanks for visiting!"

因此会向第一个用户显示第二个用户的用户名。

Recommendation

不要为任何参数(常量除外)使用 Servlet 成员字段。 (例如,确保所有成员字段都是 static final)。当开发者需要把代码内某一部分中的数据传输到另一部分时,他们经常使用 Servlet 成员字段存储用户数据。 如果您也是这么做的,可以考虑声明一个单独的类,并仅使用 Servlet “封装”这个新类。

例 2: 上述例子中的 bug 可以利用以下方式进行修正:

public class GuestBook extends HttpServlet {
protected void doPost (HttpServletRequest req,
HttpServletResponse res) {
GBRequestHandler handler = new GBRequestHandler();
handler.handle(req, res);
}
}
public class GBRequestHandler {
String name;
public void handle(HttpServletRequest req,
HttpServletResponse res) {
name = req.getParameter("name");
...
out.println(name + ", thanks for visiting!");
}
}

此外, Servlet 也可以利用同步代码块来访问 servlet 实例变量。但是,使用同步代码块可能会导致严重的性能问题。

最新文章

  1. html中table边框属性
  2. Maven 整合FreeMarker使用
  3. CSS3之过渡及2D变换
  4. [地图SkyLine二次开发]框架(5)完结篇
  5. Mysql如何修改unique key
  6. 【转】Lua coroutine 不一样的多线程编程思路
  7. javascript/jquery判断是否为undefined或是null!
  8. php 获取目录下文件列表
  9. 【原创】javascript——prototype与__proto__
  10. iOS-你真的会用UIMenuController吗?(详细)
  11. android 程序防止被360或者系统给kill掉
  12. iOS 蓝牙4.0开发
  13. 指针与数据结构算法_链表(C语言)
  14. my97自定义事件
  15. plsql 数据迁移——导出表结构,表数据,表序号
  16. eclipse中Cannot change version of project facet Dynamic Web Module to 2.5.
  17. Factor Pattern----工厂模式
  18. Nginx从入门到实践(二)
  19. Appium + Python 测试 QQ 音乐 APP的一段简单脚本
  20. 在Visual Studio 2017中安装bower

热门文章

  1. 1.记我的第一次python爬虫爬取网页视频
  2. NuGet 应用指南
  3. Linux系统安装JDK8
  4. C++ 字符串中子串个数
  5. day14 参数
  6. vue+element-ui JYAdmin后台管理系统模板-集成方案【项目搭建篇2】
  7. java 面向对象(四十):反射(四)反射应用一:创建运行时类的对象
  8. Mysql and ORM
  9. 有效提高java编程安全性的12条黄金法则
  10. Python基础-类与对象