请教:既然spring mvc 默认是单例模式,那么在高并发多线程环境下service和controller加上synchronized

既然spring mvc 默认是单例模式,那么在高并发多线程环境下service和controller加上synchronized还有必要吗?

在service和controller加上synchronized有啥不同?总感觉反正两次不同的request,controller的实例是不同的,所以在controller中加入synchronized是没有必要的

只需要对能被多个线程访问(存在修改的场景)的变量进行线程安全方面的编码即可

你提出这个问题就说明对相关知识了解有点模糊,建议了解下java的内存模型,我能力有限,无法简单描述出来

就是因为Spring MVC是单例模式,所以在你的Controller里不能写有成员变量(scope设成Prototype除外),因为不同的请求会公用这个实例而不是新开一个实例(单例模式减小开销,增加性能),所以你在

private <span style="color: #FF0000;">synchronized</span>  T get(@RequestBody T json)

更要加上这个synchronized,因为下一个请求会覆盖上一次这个@RequestBody,所以你可以用 

@Autowired

    protected  HttpServletRequest _request;

这个_request每次是不同的实例(具体可以看底层源代码)

总感觉反正两次不同的request,controller的实例是不同的

确定?

如果涉及到金钱,就很危险了

并发控制加在业务逻辑处理上吧,加在controller能有用么

扫描二维码关注公众号,回复: 9922424 查看本文章

 既然是单例模式,那么controller的成员变量肯定是同一个变量。多线程情况下使用的都是同一个变量。
     这里既然有了分层  那么只需要把service层的对象作为controller的成员变量,而在方法你调用service层的方法。使用的 相关变量都放在service层里(共用的可以使用单例,不共用的还是不能使用单例)(这个是常用的写法而已,你想怎么写我也管不到,说了这么多废话,其 实我就是想说单例模式下成员变量是不变的)
   其实在实际开发中还有个很强大的框架Spring ,别忘了他可以动态加载变量。如果你想使用成员变量,但是又只是当前线程使用,那么使用Spring动态加载就可以了
   好了废话说了这么多......其实对于你的问题synchronized没必要加。或者说考虑到性能的某些情况下是不能加

以前写在contrller,现在改了再service

好像这篇文章做法是由于事务,然后sychronized直接写在controller.
https://www.jianshu.com/p/6f58346fe95e

单例模式 和加不加synchronized有关吗?  单利模式保证了 只能创建一个实例;而synchronized 是同步锁,可以作用类和方法。 你在高并发下,只能保证一直存在一个实例,想象是对象也可以,但是假如你的业务要求某个方法要保证同一时间只能一个人调用,你就需要加 synchronized关键字了。这两个概念没什么关联,看自己业务需求

单例没有成员变量就不需要

@scope("request") 每次请求会生成新的实例

不需要,加上也没有意义

同10L,两个概念。
  多线程是说一块儿代码(比如你查完了100个对应到pojo的数据,用list<pojo>接了,完了你要输出,以打到控制台为 例,while(){if(输出)else{}}),你正常执行是顺序的,计数器指针一次次变化,
lrc歌词一条条的执行。而使用多线程的话,可以并发执行,3个人 一起往一个地方写,速度会比单线程快。synchronized是同步锁,他把你并发执行中有可能出数据安全问题的地方锁起来,让同一时间,只有一个人能 干这事儿。好比3个人,都进了while判断,准备往上写了,但是进判断时候,用来计数的量都是1,那他们都写list.get(index:1),肯定 是不行的,所以把这块儿代码加锁,1写完了换笔芯去,纸就释放给其他人写了,他可以在这个时间段做没锁的操作,而不必等他其他人写完(这也是多线程的优 势),比如再走到桌前。2这个时候输出,此时的计数量已经在线程1的加锁代码里变动过了,他就知道写的是第二个(当时不一定是2先写,看系统调度,比如2 手抽筋没拿起笔来,就是3先碰到纸,那就3先写。)
  单例多例说的是容器里面怎么个存在形式。默认单例是容器里只有一个实例对象,你getBean得到的是同一个,多例是每次调用(new了一个被注入bean的对象),给的是新的bean。
  至于你说的多线程并发,如果是指具体做一个操作,想并发做来提速,那就是加锁,或者优化代码。如果是纠结controller层面的则可不比,首先, 你controller里都是方法,不涉及实例变量。其次,应对请求分配线程处理的是servlet容器(也就是tomcat之类的)。这些做容易的服务 器不能处理多线程只能串行,那它也不会成为我们现在常用的web服务器。

发布了79 篇原创文章 · 获赞 2 · 访问量 2281

猜你喜欢

转载自blog.csdn.net/liuji0517/article/details/104587947