关于实例变量和静态变量的一点疑问

(以下所述只在WEB程序中)
近期在项目调试时遇到一个关于Servlet的实例变量的问题,由于Servlet是多线程的,所以Servlet的实例变量是非线程安全的,在项目调试中出现多线程的同步问题。
由于Web容器维护的Servlet在容器中只会创建一个实例,也就单例模式。Servlet多线程运行,则实例变量是多线程共享的,存在隐患,但很难发现!
下面来说一下这个问题,比较离奇:
原先的jsp页面中,存在一个Hidden的Iframe来实现页面上菜单联动的功能,一直运行良好。最近把iframe去掉了,改用ajax来实现。在下拉菜单onchange时,同时发出三个请求,调用同一个servlet,在这个Servlet中存在一个实例变量来返回数据,由于线程变量是非线程安全的,所以出现了bug,这个bug很隐秘,不是每次都能测试出来。
在这里我不想讨论iframe和ajax的好坏,只是想讨论一下实例变量和静态变量。
静态变量大家肯定比较熟悉,使用静态变量就是为了维护一个状态,使得可以让多实例共享这个变量,我们可以用它来实现一些类似缓存的功能。现在如果这个类的实现是一个单例的模式,那么静态变量就失去了优势。单例,那就意味着只能多线程使用,那么多线程中实例变量就是多线程共享的(非线程安全),此时实例变量的作用类似于静态变量了。
是不是可以这样说,单例模式中可以用实例变量来实现静态变量的功能呢?? 现在Spring中默认的都是单例模式(singleton)。
但是个人观点,不提倡使用实例变量,毕竟非线程安全。如果一定要使用的话,个人观点只用实例变量来维护一些web资源(缓存功能,如xml资源等等,公司项目中有很多这样的情况),不能在这个类中频繁使用它,不安全(我遇到的就是这样一个问题)。
纯属个人观点,欢迎大家发表意见,讨论一下!

>不提倡使用实例变量,毕竟非线程安全
非常正确,是这样,玩单例或静态变量没有一点多线程和排除死锁功力,是容易陷入误区的,特别是初学者,所以以前老外有singleton is evil单例是邪恶这样极端称谓,至少是双刃剑。


单例是邪恶的:

http://www.jdon.com/jive/thread.jsp?forum=91&thread=17578

不使用实例变量 那你使用什么? 静态变量么?
既然你的servlet要在多现成环境中使用, 那么你把servlet 实现成现成安全的不就行了

静态变量也非现成安全的.

>>那么你把servlet 实现成现成安全的不就行了
怎么改成线程安全的呢,除非不使用实例变量.现在我们系统就把非必要的实例变量给去掉了

说一点我的看法. 不对的地方请指正.
1. servlet 实现线程安全和一般的java object 实现线程安全 应该没有什么太大的区别. 是可以实现的.

2. 在多线程环境下 要不你的servlet (a)完全不使用实例变量和静态变量, 成为无 状态的. 来获得线程安全性.
(b)要不就使用... 用其他办法来保证线程安全.
(c)"去掉非必要的实例变量" , 本质上对提高servlet 是线程安全特性 ,没有什么意义. 毕竟你的servlet 还包含了实例变量.

说一点我的看法. 不对的地方请指正.
1. servlet 实现线程安全和一般的java object 实现线程安全 应该没有什么太大的区别. 是可以实现的.

2. 在多线程环境下 要不你的servlet (a)完全不使用实例变量和静态变量, 成为无 状态的. 来获得线程安全性.
(b)要不就使用... 用其他办法来保证线程安全.
(c)"去掉非必要的实例变量" , 本质上对提高servlet的线程安全特性没有什么意义. 毕竟你的servlet 还包含了实例变量.

>不使用实例变量 那你使用什么? 静态变量么?
不使用“变量”,使用”对象“,照顾设计每个对象的生命周期scope,每个对象都是有生命的,有始有终,一切皆变,没有不变。

试图使用不变来表达变化的需求,这是传统面向过程设计的死穴!

关于线程安全,本人的看法是多使用方法变量而不是实例变量。如果非要使用实例变量,可能得用常量!