码迷,mamicode.com
首页 > 编程语言 > 详细

spring singleton scope与singleton pattern的区别

时间:2014-07-03 14:33:14      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:spring singleton scope与singleton pattern的区别

单态定义:
    Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。

    在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。

还有, singleton能够被状态化; 这样,多个单态类在一起就可以作为一个状态仓库一样向外提供服务,比如,你要论坛中的帖子计数器,每次浏览一次需要计数,单态类能否保持住这个计数,并且 能synchronize的安全自动加1,如果你要把这个数字永久保存到数据库,你可以在不修改单态接口的情况下方便的做到。

    另外方面,Singleton也能够被无状态化。提供工具性质的功能,Singleton模式就为我们提供了这样实现的可能。使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage collection)。                 
    我们常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。                                 

如何使用?
一般Singleton模式通常有几种形式:

饱汉式

public class Singleton {

  private Singleton(){}

  //在自己内部定义自己一个实例,是不是很奇怪?
    //注意这是private 只供内部调用

  private static Singleton instance = new Singleton();

  //这里提供了一个供外部访问本class的静态方法,可以直接访问  
    public static Singleton getInstance() {
        return instance;   
    }
}

饿汉式

public class Singleton {

  private static Singleton instance = null;
    public static synchronized Singleton getInstance();
    if (instance==null){                              

        instance=new Singleton();
        return instance;   

    }

}

    使用Singleton.getInstance()可以访问单态类。

    上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。

    注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。关于lazy                  initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴趣者进一步研究。

一般认为第一种形式要更加安全些。               

使用Singleton注意事项
    有时在某些情况下,使用Singleton并不能达到Singleton的目的,如有多个Singleton对象同时被不同的类装入器装载;在EJB这样的分布式系统中使用也要注意这种情况,因为EJB是跨服务器,跨JVM的。

我们以SUN公司的宠物店源码(Pet Store 1.3.1)的ServiceLocator为例稍微分析一下:
    在Pet Store中ServiceLocator有两种,一个是EJB目录下;一个是WEB目录下,我们检查这两个ServiceLocator会发现内容差不 多,都是提供EJB的查询定位服务,可是为什么要分开呢?仔细研究对这两种ServiceLocator才发现区别:在WEB中的 ServiceLocator的采取Singleton模式,ServiceLocator属于资源定位,理所当然应该使用Singleton模式。但是 在EJB中,Singleton模式已经失去作用,所以ServiceLocator才分成两种,一种面向WEB服务的,一种是面向EJB服务的。

    Singleton模式看起来简单,使用方法也很方便,但是真正用好,是非常不容易,需要对Java的类 线程 内存等概念有相当的了解。

    总之:如果你的应用基于容器,那么Singleton模式少用或者不用,可以使用相关替代技术。


        所有的业务对象中的成员变量如,在Dao中的xxxDao,或controller中的xxxService,都会被多个线程共享,那么这些对象不会出现同步问题吗,比如会造成数据库的插入,更新异常? 

        xxxDao的同步问题已经由持久化框架mybatis或hibernate的封装不用担心【其解决方案很有可能就是使用ThreadLocal,见下面】而我们注入并实例化xxxService只是为了调用xxxService的方法,不会引起同步问题;private static final类型的变量是不会改变的;最好尽量避免全局static类型的变量,防止多线程修改,引起同步问题。

        当使用ThreadLocal维护变量[仅仅是变量,因为线程同步的问题就是成员变量的互斥访问出问题]时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。原理概念:为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。【每个线程其实是改变的是自己线程的副本,而不是真正要改变的变量,所以效果就是每个线程都有自己的,“这其实就将共享变相为人人有份!”】 虽然使用ThreadLocal会带来更多的内存开销,但这点开销是微不足道的。因为保存在ThreadLocal中的对象,通常都是比较小的对象。


        实体bean从客户端传递到后台的controller-->service-->Dao,这一个流程中,他们这些对象都是单例的,那么这些单例的对象在处理我们的传递到后台的实体bean会出问题吗? 

        实体bean不是单例的,并没有交给spring来管理,每次只是手动的new出来的【如EMakeType et = new EMakeType();】,所以即使那些处理我们提交数据的业务处理类是被多线程共享的,但是他们处理的数据并不是共享的,数据是每一个线程都有自己的一份,所以在数据这个方面是不会出现线程同步方面的问题的;

refer to:Spring中Singleton模式的线程安全


spring singleton scope与singleton pattern的区别

    一:对于Spring中实现Singleton模式,是以IOC容器为单位(就是说在这个容器里面bean实现Singleton),换句话说,一个JVM可能有多个IOC容器,而在这个容器里实现了singleton bean
Java中实现Singleton模式而言,只有一个JVMjvm中某个class只有一个实例

    二:singleton模式中,singletonclass在整个JVM中只有一个instanceSpringBean,你可以一个class配置多个Bean,这个class就有了多个instance。这个singleton是指在spring容器中,这个Bean是单实例的,是线程共享的。所以要求这些类都是线程安全的。也就是说,不能出现修改Bean属性的方法,当然除了设值得那些setter。只要满足线程安全,这些bean都可以用singleton。而且我们在绝大多数使用上,也是这样用的,包括dao,service
    BeanfactorySpring初始以静态方式载入的,Spring的单例IOC是基于容器级的,所以这你都不用担心与考虑.


spring singleton scope与singleton pattern的区别,布布扣,bubuko.com

spring singleton scope与singleton pattern的区别

标签:spring singleton scope与singleton pattern的区别

原文地址:http://jasonwalker.blog.51cto.com/7020143/1433686

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!