关于singleton的线程安全问题

关于singleton的线程安全问题

老师好,教学影片从12:55开始,原文:

『当userService被创建,userDao是哪个类也就确定了,绝大多数情况下我们不会对userDao这个属性重新做设置,这也意味着作为userDao,他在userService中是稳定不变的』


根据老师原文的意思,当userService与userDao都在singleton的设定下,大多数情况不会出现线程安全问题,但我仍不太理解,以下是我的看法与疑问,还请老师协助解惑及纠正。


在Ioc容器启动时,设置为singleton的bean会自动被创建,但在外部调用实例时,仍然会对实例进行set与get的动作。  此时假设有两个使用者 「同时」 对server发出请求(假设是update),由于是singleton,此时service会调用同一个DAO,并且同时修改了DB中的同一条数据,那我会认为此时会有线程安全问题。


问题一:

想请这样理解是对的吗?与老师所说的不会有线程安全问题的理解上差异在哪呢?


问题二:

老师所说的dao在service中是稳定不变的,此时是指dao是写死的状态吗? 请问该怎麽理解「稳定不变」的意思呢?



正在回答

登陆购买课程后可参与讨论,去登陆

1回答

同学你好,1、当设置为单例时,并不是不会引发线程安全问题。相反的,确实会引发线程安全问题。但是这里依然使用单例的原因是,当Service和Dao的实现类对象创建完成之后,并不会再对其属性进行更改。也就是说,不会发生同学描述的多个线程对其属性进行set的情况。

    但是,如果在业务中,确实需要对其属性进行更改时,就会发生线程安全问题。此时就不建议使用单例模式了,而是改为prototype,以保证每个线程操作自身独立的对象。

2、“稳定不变”是指其属性的值(无论是具体数值还是引用的对象)是不会进行更改的,也就是说内容不会改变。而“写死”是指在书写代码时,应当使用变量的位置没有使用变量,而是使用常量。例如:年龄应当使用变量,但是如果年龄位置固定写为18岁,就称之为“写死”。

祝学习愉快!

  • weixin_慕仙7241916 提问者 #1

    很抱歉,我还是不理解,为何单例模式就可以避免线程安全问题? 同时访问同一个对象不就是造成线程安全的主因吗? 还是说我们现在所讨论的单例,实际上是有在类上加synchronized的?


    第二点是老师说的,「稳定不变」是  不会产生线程问题的主因,"service一直使用这个类"的这个解释,似乎不是解决线程安全问题的答案?

    2022-09-08 17:58:44
  • 同学你好,1、刚老师理解有误,已修改回答同学可以查看一下。给您的学习带来不便,深感抱歉!

    2、并不是添加synchronized关键字。在单例模式情况下,不对对象中属性进行修改,是不会发生线程安全的问题。当需要修改属性时是会出现同学描述的情况(线程问题)。

    3、刚是老师理解错误,稳定不变,描述的是属性值。

    祝学习愉快!

    2022-09-08 18:18:02
  • 谢谢小尤老师的回答!这样我能完全理解,但又有几个衍伸问题想了解。


    问题一:

    在实际业务中,使用prototype可以解决在Java中的线程线程安全问题,但是在写入DB的时后,仍然会有DB本身的线程安全问题,并且需要使用"锁"来解决,请问这样理解正确吗?


    问题二:

    关于DAO的实现类对象在创建时不会再对属性进行更改,意思是DAO本身是不带任何参数的吗?


    因为在我的理解中,DAO不都是要接收Service丢进来的参数吗,为何会是使用常量,例如要带入的where条件,用来实现某个业务功能(任何CRUD),在进行这些操作的时后不都会需要set吗? 请问要如何理解所谓的稳定不变,以及不会再进行set呢? 请问能举例帮助理解吗?

    2022-09-08 19:39:02
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星

相似问题

登录后可查看更多问答,登录/注册

请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师