日期:2014-05-19  浏览次数:21003 次

单例模式线程为什么不安全?
在学习spring框架的时候 一个bean的范围可以是singleton和prototype
singleton模式线程是不安全的,在学JSP的时候也涉及到这些内容
现在来提问下,为什么设置singlton后,会存在线程不安全问题
线程不安全主要表现在哪里?

------解决方案--------------------
引用楼主 fengjssy 的帖子:
在学习spring框架的时候 一个bean的范围可以是singleton和prototype
singleton模式线程是不安全的,在学JSP的时候也涉及到这些内容
现在来提问下,为什么设置singlton后,会存在线程不安全问题
线程不安全主要表现在哪里?

------解决方案--------------------
单例中有个部分,就是有个对象作为这个类的成员变量被保存,而不是作为局部变量,所以其他方法发生并发访问这个对象时其实是在操作同一个对象。
举个例子,两个人同时调用一个方法(给我蛋糕),但这个方法返回一个蛋糕的单例对象,两个人同时获得了同一个蛋糕,并坐下,举起刀叉,结果第一个人先吞了蛋糕,就造成了第二个人明明得到了蛋糕,却没能吃到这个结果。
------解决方案--------------------
引用楼主 fengjssy 的帖子:
在学习spring框架的时候 一个bean的范围可以是singleton和prototype
singleton模式线程是不安全的,在学JSP的时候也涉及到这些内容
现在来提问下,为什么设置singlton后,会存在线程不安全问题
线程不安全主要表现在哪里?

------解决方案--------------------
单例顾名思义就是只有一份数据的意思,当你同时对一份数据进行操作时,就会导致数据不一致,这就是所谓的线程不安全。
数据库是单例的一个典型代表,在数据库中存在读脏数据、不可重复读、幻读就是因为同时操作一份数据的原因。
比如有一个表,存储火车票信息,其中字段有火车票的总数,
A买火车票,操作取出火车票总数(假如是100),减一,再将99存进去。
在A买的同时,另一个窗口的B也在买车票,操作取出火车票总数,由于A还没有买到车票,所以他取出来的总数也是100,减一,再将99存进去。
此时,火车站出售了两张票,而记录显示是出售一张,这就是因为B读取数据时,出现了读脏数据。
详细内容 参考 数据库的教材

当action中不存在成员变量时,不会出现线程不安全的问题,如果存在就需要加锁,保证线程安全。
什么是加锁,简单的讲就是买票的时候要排队,前面的没买完,你就不能买。当然还有别的解决方案,比如通过版本号来区别,我就不多讲了。