Controller方法加了synchronized , service的方法就不用加synchronized 了吧?

Controller方法加了synchronized , service的方法就不用加synchronized 了吧?假如说这个service只有这一个Controller调用。

这样就能做到只有一个线程访问,对吗?

嗯,个人感觉加在 service 要好一点,因为串行化的代码变短了。而且处理逻辑的也是在service。加到入口,那么controller,service线程都是串行的,类比HashmapCounrrentHashmapCounrrentHashmap里面有个分段锁,就是为了缩短synchronized修饰的区域。

可以对比这两种单例的写法:

  • 懒汉式加同步方法

    public class Singleton {
      // 实例变量
      private byte[] bate = new byte[1024];
      // 私有的构造函数,即不允许外部 new
      private Singleton(){ }
    
      private static  Singleton singleton =null;
      public static synchronized Singleton getInstance0(){
          if (singleton == null) {
              singleton = new Singleton();
          }
          return singleton;
      }
    
  • 双重效验锁单例

    public class Singleton {
      // 实例变量
      private byte[] bate = new byte[1024];
      // 私有的构造函数,即不允许外部 new
      private Singleton(){ }
    
      private  static volatile Singleton singleton2 = null;
      public static Singleton getInstance4() {
    
          if (singleton2 == null){
              synchronized (Singleton.class){
                  if (singleton2 ==null){
                      singleton2 = new Singleton();
                  }
              }
          }
          return singleton2;
      }
    

一般加Service,加controller,如果Service只有它调用的话,那么 controller和Service是都是串行的,但是加Service里能缩小锁的粒度,能加快controller里的可以并行的逻辑,如果controller里的都是不能并行的,建议下沉到service

没问题,能实现。但是不建议这样搞。啥业务需求啊?可以说说看,这样代价很高,兴许有更好的办法呢。

应该加在service的方法好一点,但只要加一个。

如果都加了的话,看下实际的处理业务的代码在哪里.可以优化一下同步代码,这样的话可以减少上锁的时间.

  1. spring 实例化对象,默认都是单例的,所以synchronized加在controller和service中的一个就行了。
  2. 加在哪合适,一般是同步的代码越少越好,范围越小越好。就controller和service来说,加在service比较好,因为通常controller不会写业务逻辑。如果controller有必须同步的代码,建议把代码移到service。如果实在移不好,那么最好这个controller就独立出来,只做这一件事情。
  3. 另外service还有其他controller调用也没关系,synchronized本来就是处理多线程并发问题的
  4. 还有一些并发问题不是纯代码造成的,只加synchronized也不能完全解决问题。例如select for update 类型的问题,只在代码里加synchronized也不行的。