非单例模式在多线程中是否线程安全?

林蜗牛snail 2019-03-18 04:41:14

@RestController
public class helloworld {

private int count;

@RequestMapping("/hello")
public String hello(){
count++;
return "hello world";

}}

假设上面这个controller是多例的,有没有这么一个场景,在我项目运行时,同时有两个线程持有helloworld同一个实例? 就是持有同一个变量count的副本拷贝。
如果是单例模式,那么毫无疑问会持有同一个实例,那如果是多例,小明和小王两个人同时运行我的项目,做什么操作才会有线程安全问题,才会有同一份helloworld实例呢?

不知道我有没有表述清楚
...全文
158 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
stacksoverflow 2019-03-18
  • 打赏
  • 举报
回复
引用 8 楼 林蜗牛snail 的回复:
[quote=引用 5 楼 stacksoverflow 的回复:] [quote=引用 4 楼 林蜗牛snail 的回复:] [quote=引用 2 楼 stacksoverflow 的回复:] 如果你能保证每个请求过来new一个实例的话,没有任何问题。 但这个controller是在spring容器中管理的,你需要了解spring对你的配置方式,每个请求是不是都new一个实例。
springMVC的controller默认是单例的,上面举的例子只是为了简单起见,没有实用性可言。 我贴一个我在网上看到一位网友的评论: 无论是单例还是多例,只要是方法内部的局部变量,都是线程安全地,你可以放心的用。 但如果是全局变量,对于单例来说,这个单例类只有一个实例对象,所有的线程都访问这一个对象,也就是都是访问的同一个对象的同一个全局变量,这时候是有线程同步问题的;对于多例来说,多例类可以创建多个对象,如果创建了两个对象A1,A2,那么这个全局变量在内存中是两份,一份属于A1,一份属于A2,两个线程分别修改A1的变量,A2的变量,修改的是两个副本,所以不存在同步问题;但是如果两个线程都访问对象A1,这时候两个线程范访问的就是同一个全局变量了,就存在线程安全问题。 我就是对他最后那句话疑惑,什么场景会出现两个线程同时访问到对象A1? [/quote] 你可以忽略那句话。 不知道下面场景能否解决你的疑问: 一般用对象池会有你说你的问题,比如servlet是线程不安全的,因为tomcat容器在线程池了保存了多个servlet实例,很可能两个不同时间过来的线程拿到同一个实例。[/quote] servlet是单例的,在web容器中只有一个servlet实例,所以不同线程拿到的servlet实例是同一个,所以是线程不安全的。 但是我的疑惑是,如果是多例的,什么情况,什么场景下会出现两个线程拿到同一个实例。。。[/quote] serlvet是不是单例的,spring用的dispacherServlet是单例的。 看看6楼是不是你说的场景?
林蜗牛snail 2019-03-18
  • 打赏
  • 举报
回复
引用 5 楼 stacksoverflow 的回复:
[quote=引用 4 楼 林蜗牛snail 的回复:]
[quote=引用 2 楼 stacksoverflow 的回复:]
如果你能保证每个请求过来new一个实例的话,没有任何问题。
但这个controller是在spring容器中管理的,你需要了解spring对你的配置方式,每个请求是不是都new一个实例。

springMVC的controller默认是单例的,上面举的例子只是为了简单起见,没有实用性可言。
我贴一个我在网上看到一位网友的评论:
无论是单例还是多例,只要是方法内部的局部变量,都是线程安全地,你可以放心的用。 但如果是全局变量,对于单例来说,这个单例类只有一个实例对象,所有的线程都访问这一个对象,也就是都是访问的同一个对象的同一个全局变量,这时候是有线程同步问题的;对于多例来说,多例类可以创建多个对象,如果创建了两个对象A1,A2,那么这个全局变量在内存中是两份,一份属于A1,一份属于A2,两个线程分别修改A1的变量,A2的变量,修改的是两个副本,所以不存在同步问题;但是如果两个线程都访问对象A1,这时候两个线程范访问的就是同一个全局变量了,就存在线程安全问题。
我就是对他最后那句话疑惑,什么场景会出现两个线程同时访问到对象A1? [/quote]

你可以忽略那句话。
不知道下面场景能否解决你的疑问:
一般用对象池会有你说你的问题,比如servlet是线程不安全的,因为tomcat容器在线程池了保存了多个servlet实例,很可能两个不同时间过来的线程拿到同一个实例。[/quote]
servlet是单例的,在web容器中只有一个servlet实例,所以不同线程拿到的servlet实例是同一个,所以是线程不安全的。
但是我的疑惑是,如果是多例的,什么情况,什么场景下会出现两个线程拿到同一个实例。。。
ml_dark 2019-03-18
  • 打赏
  • 举报
回复
非单例模式在多线程里肯定是线程安全的,每个线程持有的对象都是独立的
stacksoverflow 2019-03-18
  • 打赏
  • 举报
回复
或者说(手敲得不保证能运行) public class A extends Thread{ private B b; public A(B b){ this.b = b; } public void run(){ b.xxx } } ///test B b = new B(); A a1 = new A(b); A a2 = new A(b); a1.start(); a2.start(); a1和a2就访问的同一个b
stacksoverflow 2019-03-18
  • 打赏
  • 举报
回复
引用 4 楼 林蜗牛snail 的回复:
[quote=引用 2 楼 stacksoverflow 的回复:] 如果你能保证每个请求过来new一个实例的话,没有任何问题。 但这个controller是在spring容器中管理的,你需要了解spring对你的配置方式,每个请求是不是都new一个实例。
springMVC的controller默认是单例的,上面举的例子只是为了简单起见,没有实用性可言。 我贴一个我在网上看到一位网友的评论: 无论是单例还是多例,只要是方法内部的局部变量,都是线程安全地,你可以放心的用。 但如果是全局变量,对于单例来说,这个单例类只有一个实例对象,所有的线程都访问这一个对象,也就是都是访问的同一个对象的同一个全局变量,这时候是有线程同步问题的;对于多例来说,多例类可以创建多个对象,如果创建了两个对象A1,A2,那么这个全局变量在内存中是两份,一份属于A1,一份属于A2,两个线程分别修改A1的变量,A2的变量,修改的是两个副本,所以不存在同步问题;但是如果两个线程都访问对象A1,这时候两个线程范访问的就是同一个全局变量了,就存在线程安全问题。 我就是对他最后那句话疑惑,什么场景会出现两个线程同时访问到对象A1? [/quote] 你可以忽略那句话。 不知道下面场景能否解决你的疑问: 一般用对象池会有你说你的问题,比如servlet是线程不安全的,因为tomcat容器在线程池了保存了多个servlet实例,很可能两个不同时间过来的线程拿到同一个实例。
林蜗牛snail 2019-03-18
  • 打赏
  • 举报
回复
引用 2 楼 stacksoverflow 的回复:
如果你能保证每个请求过来new一个实例的话,没有任何问题。
但这个controller是在spring容器中管理的,你需要了解spring对你的配置方式,每个请求是不是都new一个实例。

springMVC的controller默认是单例的,上面举的例子只是为了简单起见,没有实用性可言。
我贴一个我在网上看到一位网友的评论:
无论是单例还是多例,只要是方法内部的局部变量,都是线程安全地,你可以放心的用。 但如果是全局变量,对于单例来说,这个单例类只有一个实例对象,所有的线程都访问这一个对象,也就是都是访问的同一个对象的同一个全局变量,这时候是有线程同步问题的;对于多例来说,多例类可以创建多个对象,如果创建了两个对象A1,A2,那么这个全局变量在内存中是两份,一份属于A1,一份属于A2,两个线程分别修改A1的变量,A2的变量,修改的是两个副本,所以不存在同步问题;但是如果两个线程都访问对象A1,这时候两个线程范访问的就是同一个全局变量了,就存在线程安全问题。
我就是对他最后那句话疑惑,什么场景会出现两个线程同时访问到对象A1?
stacksoverflow 2019-03-18
  • 打赏
  • 举报
回复
但是可以说你这种写法在实际项目中代码评审时肯定通不过的。
stacksoverflow 2019-03-18
  • 打赏
  • 举报
回复
如果你能保证每个请求过来new一个实例的话,没有任何问题。 但这个controller是在spring容器中管理的,你需要了解spring对你的配置方式,每个请求是不是都new一个实例。
maradona1984 2019-03-18
  • 打赏
  • 举报
回复
如果spring的prototype用到了对象池,那你这代码是不会出现线程安全的
当然我是不知道他到底用了没有

50,523

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧