u013179958
CSDNRGY
采纳率99.5%
2017-12-10 06:34 阅读 1.5k
已采纳

静态化service,dao,为什么不会引发线程安全问题

5
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

9条回答 默认 最新

  • 已采纳
    qq87419406 netlocks 2017-12-10 08:52

    和Struts一样,Spring的Controller默认是Singleton的,这意味着每个request过来,系统都会用原有的instance去处理,这样导致了两个结果:一是我们不用每次创建Controller,二是减少了对象创建和垃圾收集的时间;由于只有一个Controller的instance,当多个线程调用它的时候,它里面的instance变量就不是线程安全的了,会发生窜数据的问题。
    当然大多数情况下,我们根本不需要考虑线程安全的问题,比如dao,service等,除非在bean中声明了实例变量。因此,我们在使用spring mvc 的contrller时,应避免在controller中定义实例变量。
    如:
    [java] view plain copy
    public class Controller extends AbstractCommandController {

    ......

    protected ModelAndView handle(HttpServletRequest request,HttpServletResponse response,

    Object command,BindException errors) throws Exception {

    company = ................;

    }

    protected Company company;

    }

    在这里有声明一个变量company,这里就存在并发线程安全的问题。
    如果控制器是使用单例形式,且controller中有一个私有的变量a,所有请求到同一个controller时,使用的a变量是共用的,即若是某个请求中修改了这个变量a,则,在别的请求中能够读到这个修改的内容。。

    有几种解决方法:
    1、在Controller中使用ThreadLocal变量
    2、在spring配置文件Controller中声明 scope="prototype",每次都创建新的controller
    所在在使用spring开发web 时要注意,默认Controller、Dao、Service都是单例的。

    点赞 评论 复制链接分享
  • niechenhu niechenhu 2017-12-10 07:40

    private static final 本身就是线程安全的

    点赞 评论 复制链接分享
  • weixin_41339885 weixin_41339885 2017-12-10 08:15

    private static final 本身就是线程安全的

    点赞 评论 复制链接分享
  • qq_25304749 qq_25304749 2017-12-10 09:13

    和Struts一样,Spring的Controller默认是Singleton的,这意味着每个request过来,系统都会用原有的instance去处理,这样导致了两个结果:一是我们不用每次创建Controller,二是减少了对象创建和垃圾收集的时间;由于只有一个Controller的instance,当多个线程调用它的时候,它里面的instance变量就不是线程安全的了,会发生窜数据的问题。
    当然大多数情况下,我们根本不需要考虑线程安全的问题,比如dao,service等,除非在bean中声明了实例变量。因此,我们在使用spring mvc 的contrller时,应避免在controller中定义实例变量。
    如:
    [java] view plain copy
    public class Controller extends AbstractCommandController {

    ......

    protected ModelAndView handle(HttpServletRequest request,HttpServletResponse response,

    Object command,BindException errors) throws Exception {

    company = ................;

    }

    protected Company company;

    }

    在这里有声明一个变量company,这里就存在并发线程安全的问题。
    如果控制器是使用单例形式,且controller中有一个私有的变量a,所有请求到同一个controller时,使用的a变量是共用的,即若是某个请求中修改了这个变量a,则,在别的请求中能够读到这个修改的内容。。

    有几种解决方法:
    1、在Controller中使用ThreadLocal变量
    2、在spring配置文件Controller中声明 scope="prototype",每次都创建新的controller
    所在在使用spring开发web 时要注意,默认Controller、Dao、Service都是单例的。

    点赞 评论 复制链接分享
  • qq_38397797 豆豆爱痘只 2017-12-10 09:16

    因为此线程本身是安全的

    点赞 评论 复制链接分享
  • weixin_41341130 Fxouz 2017-12-10 10:25

    因为此线程本身是安全的有几种解决方法:
    1、在Controller中使用ThreadLocal变量
    2、在spring配置文件Controller中声明 scope="prototype",每次都创建新的controller
    所在在使用spring开发web 时要注意,默认Controller、Dao、Service都是单例的。

    点赞 评论 复制链接分享
  • Class_SpringCloud 强哥带你学编程 2017-12-10 11:13

    有状态和无状态呗,只要不改变大家都能访问的变量就不会出现并发问题,如果你修改你就会遇到,单例本就是不安全的,但是我在写代码的时候不改变共享变量,所以看起来是线程安全的

    点赞 评论 复制链接分享
  • qq_27718453 庄粟 2017-12-11 10:09

    你平常调用一个函数会引发线程问题吗,除非这个函数里有共享变量,比如静态变量或全局变量。
    而service,dao中是不会有人去使用静态变量或全局变量,不存在变量共享的问题,而在被调时接口上的参数是由外部传进来的,所以互不影响。

    点赞 评论 复制链接分享
  • avenccssddnn ipple1986 2017-12-13 05:42

    dao跟service其实对外只提供访问数据库CRUD的功能,不会涉及到多个线程 之间共享变量资源的问题,所以一般不管service,dao是不是静态化,都是线程安全的。

    点赞 评论 复制链接分享

相关推荐