java 细枝末节
2. 关于Thread的误解
这个误解相当常见。
我们说一个方法是否是线程安全的,判断的标准只有一个,
这个方法是否访问了 可以写的“成员变量”。(所谓的state)
注意,只有两个条件:
(1)可以改变的 (2)成员变量
如果访问了可以写的“成员变量”,那么这个方法不是 线程安全的。
如果没有访问 可以写的“成员变量”,那么这个方法是 线程安全的。
方法的线程安全特性和传进来的参数毫无关系。
举个例子说明,为什么和参数毫无关系。
- public class A {
- // 这个方法没有访问任何成员变量,本身是线程安全的。
- public void changeBuf(StringBuffer buf){
- buf.append("aaa");
- }
- };
- 公用变量
- public class Common{
- public static StringBuffer buf = new StringBuffer();
- }
- Thread 1的代码:
- A a1 = new A();
- a1.changeBuf(Common.buf);
- Thread 2的代码:
- A a2 = new A();
- a2.changeBuf(Common.buf);
我们看到,这个Common.buf还是存在共享冲突。
但这个不是A.changeBuf()方法的问题,而是调用这个方法的问题。
而且,我们看到,这里的线程安全和是否共享实例根本就没有关系。
你就是创建1000个线程,分别调用1000个不同的实例,这种调用方法还是线程不安全。
结果和这1000个线程,都调用同一个共享实例的结果,没有任何区别。
这就是说,只要你不在Action类里面声明可写的成员变量,那么多个Request使用一个共享Action,还是分别使用不同的Action,结果完全一样。
(这种情况基本没有,因为Servlet,Action就是Stateless的,没有理由声明 可写的成员变量)
类和Object实例的基本概念:
同一个类的每个Object Instance都有自己的"成员变量备份",但是所有的Object Instance都共享同一份Java代码,不管这个方法是static method还是instance method.
线程的基本概念:
每个线程有自己的运行栈。线程只在自己的运行栈上运行方法。线程只和类的方法(method)有关。线程并不和任何具体Object实例有直接关系。
由于这个问题涉及的概念比较复杂,如果有疑问,
我可以举更多详细的例子,一步一步地说明所有问题。
因为这个误解太普遍了。不解决这个误解,很多问题的讨论都是南辕北辙,根本不成立的。
(3)关于Request的误解。
我想,这个Request应该是说HttpRequest这个参数。
我想要说明的是,根据基本常识,这个HttpRequest这个参数绝不可能被共享。
我查阅了好久Tomcat的源代码,但没有找到相关的从Socket连接生成Request的代码。所以,不能提供有力的证据。只能根据常识下这个判断。
希望有了解Tomcat源代码的高手,能够指教。
发表评论
- 浏览: 78779 次
- 性别:

- 来自: 湖州

- 详细资料
搜索本博客
我的相册
共 1 张
最新评论
-
【Ext学习二】Extjs2 小 ...
//已添加自动播放功能: Ext.onReady(function() ...
-- by jianfeng008cn -
【Ext学习一】Ext 继承函 ...
fins 写道我说的是第一个问题 不是第二个空函数F的问题 我说了啊, 这些问题 ...
-- by jianfeng008cn -
【Ext学习一】Ext 继承函 ...
我搞错了,可以支持inline constructor的原因是: sb = ov ...
-- by sp42 -
【Ext学习一】Ext 继承函 ...
空函数是经典的闭包应用,用来解决继承的问题了 呵呵, 至于 "spp.cons ...
-- by sp42 -
【Ext学习一】Ext 继承函 ...
我说的是第一个问题 不是第二个空函数F的问题
-- by fins






评论排行榜