怎样理解servlet单例引起的线程安全问题

“既然servlet是单例的,就会产生产生线程安全问题“
何出此言?????

■网友
我只说结论。
【怎样理解servlet单例引起的线程安全问题】 java当中所有的并发问题都是由成员变量读写引起的,为了避免并发问题。
1.你要尽量避免多个线程共享一个对象。

2.如果一定要共享这个对象,就不要定义成员变量。

3.如果一定要定义成员变量,就要对它的读写操作加锁。
这里细说一下。
3.1.如果一个对象的成员变量有一个线程对它进行写操作,既set赋值。多个线程对它进行读操作,既get取值。就用volatile轻量级锁关键字修饰。
3.2.如果是多写多读,就请在get set方法加synchronize关键字加锁,或者用并发包下的Lock包下的显示锁加锁。

4.加锁有个缺点,每次getset都让你的线程多一步获取锁的操作。如果你不想对这个成员变量的读写方法加锁又要保证线程安全就请用Atomic包下的原子变量定义这个成员变量,它是用CAS无锁算法实现的。ConcurruntHashMap就用了它。

5.如果你既想定义成员变量又不希望它共享给多个线程从而带来并发问题,你就用ThreadLocal定义这个成员变量,它是每个线程独立使用,各自不可见的。这种方法不是锁,本质还是1。

理解线程安全问题,就要理解jvm内存模型。最后如果你想证明我说的是错误的,你就去看《Java并发编程的实践》这本书里面找找论据。

排版不好说的也不详细,先将就着吧。有人提需求我再更也不迟。


■网友
单例不一定会线程不安全,取决于类的设计。
如果Servlet类是无状态的,或者有状态但是通过合理的手段保护共享区域的话,那就是线程安全的。
线程安全或者不安全从代码层面就可以判断出来,高并发场景出现问题的几率更大而已。

■网友
谢邀
线程安全主要考虑的是对同一个数据的访问在处理 Web 请求时,多个请求是由多个线程响应的因为线程切换的顺序具有不可预知性所以对同一个数据的访问就可能发生争夺从某一个线程的角度来看就可能会出现数据不一致的情况只要不做线程安全的处理不论使用什么设计模式访问量大还是小都有可能出现线程安全问题


    推荐阅读