您的位置:首页 > Web前端 > JavaScript

【Head First Servlets and JSP】笔记9:属性的作用域、线程安全

2017-06-03 21:46 751 查看
什么是属性?

属性和参数

属性的3个作用域

属性API

属性不好的一面

1、到底什么是属性(Attribute)?

属性就是一个对象,可以被设置(bound,也可以叫绑定)到另外三个servlet API对象ServletContext、HttpSession、HttpServletRequest中。可以把它简单地认为是一个名/值对,名是String、值是object。在实际中,我们并不知道也不关心它具体如何实现,我们关心的只是属性所在的作用域。

2、属性不是参数(Parameter)!

笔记1中的参数——请求参数:



笔记7中的参数——servlet初始化参数:





以及,上下文初始化参数参数:





3、属性的3个作用域:

ServletContext属性(上下文属性)——Web应用中的每一部分都能访问

HttpSession属性(会话属性)——能访问特定的HttpSession的部分才可访问

HttpServletRequest属性(请求属性)——能访问特定的ServletRequest的部分才可访问

4、设置、访问属性的API——每个接口(ServletContext、HttpS......)的属性API完全相同



关于Enumeration,参见Java-Enumeration总结 by IAMTJW

5、属性不好的一面.··.```..``..`.`.`...`..

上下文属性不是线程安全的!一个上下文属性可能同时被多个servlet所更改、访问。糟糕的解决方案是给doGet(或者是其它方法)加上synchronized,这样并不能解决问题,原因在于synchronized只能防止同一个servlet中的其他线程访问上下文属性,但是不能阻止另外一个servlet访问。关于synchronized参见java synchronized详解 by Gang.Wang


正确的方法是:对上下文加锁,而不是对servlet加锁。怎么实现呢?看下面的代码:


会话属性是线程安全的吗?不是,因为用户可能打开好几个浏览器窗口...解决方案类似:


只有请求属性和局部变量是线程安全的!


要注意的是servlet的实例域不是线程安全的,除非实现了SingleThreadModel,或者是同步服务方法,但这是十分糟糕的做法,会让Web应用的效率变得非常差,所以,一个servlet根本不该有实例变量,有也应该是final的,如果真的需要在多个线程中共享一些东西,那就把它加到合适的作用域上去。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐