`

java的学习

 
阅读更多

详细内容及例子:http://blog.csdn.net/jason0539/article/details/23297037/

单例模式有以下特点:1、单例类只能有一个实例。

2、单例类必须自己创建自己的唯一实例。

3、单例类必须给所有其他对象提供这一实例。

举例:

懒汉式单例类://懒汉式单例类.在第一次调用的时候实例化自己 

 

    public class Singleton {  
        private Singleton() {}  
        private static Singleton single=null;  
        //静态工厂方法   
        public static Singleton getInstance() {  
             if (single == null) {    
                 single = new Singleton();  
             }    
            return single;  
        }  
    }  

 <1>将构造方法限定为private避免了类在外部被实例化

<2>在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。

实际上:通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。(单例模式被java反射机制攻击)

缺点:没有考虑到线程安全,所以我们对getInstance()方法进行改造----------->

懒汉式单例类:

   (加同步锁)

    public static synchronized Singleton getInstance() {  
             if (single == null) {    
                 single = new Singleton();  
             }    
            return single;  
    }  

   (加双重校验锁的懒汉式)

  

    public static Singleton getInstance() {  
            if (singleton == null) {    
                synchronized (Singleton.class) {    
                   if (singleton == null) {    
                      singleton = new Singleton();   
                   }    
                }    
            }    
            return singleton;   
        }  

  (静态内部类)既实现了线程安全,又避免了同步带来的性能影响。

    public class Singleton {    
        private static class LazyHolder {    
           private static final Singleton INSTANCE = new Singleton();    
        }    
        private Singleton (){}    
        public static final Singleton getInstance() {    
           return LazyHolder.INSTANCE;    
        }    
    }    

 二、饿汉式单例//饿汉式单例类.在类初始化时,已经自行实例化 

public class Singleton1 {  
    private Singleton1() {}  
    private static final Singleton1 single = new Singleton1();  
    //静态工厂方法   
    public static Singleton1 getInstance() {  
        return single;  
    }  
}  

 饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。

三、登记式单例(可忽略)

    //类似Spring里面的方法,将类名注册,下次从里面直接获取。  
    public class Singleton3 {  
        private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();  
        static{  
            Singleton3 single = new Singleton3();  
            map.put(single.getClass().getName(), single);  
        }  
        //保护的默认构造子  
        protected Singleton3(){}  
        //静态工厂方法,返还此类惟一的实例  
        public static Singleton3 getInstance(String name) {  
            if(name == null) {  
                name = Singleton3.class.getName();  
                System.out.println("name == null"+"--->name="+name);  
            }  
            if(map.get(name) == null) {  
                try {  
                    map.put(name, (Singleton3) Class.forName(name).newInstance());  
                } catch (InstantiationException e) {  
                    e.printStackTrace();  
                } catch (IllegalAccessException e) {  
                    e.printStackTrace();  
                } catch (ClassNotFoundException e) {  
                    e.printStackTrace();  
                }  
            }  
            return map.get(name);  
        }  
        //一个示意性的商业方法  
        public String about() {      
            return "Hello, I am RegSingleton.";      
        }      
        public static void main(String[] args) {  
            Singleton3 single3 = Singleton3.getInstance(null);  
            System.out.println(single3.about());  
        }  
    }  

 登记式单例实际上维护了一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从Map直接返回,对于没有登记的,则先登记,然后返回。 

这里我对登记式单例标记了可忽略,我的理解来说,首先它用的比较少,另外其实内部实现还是用的饿汉式单例,因为其中的static方法块,它的单例在类被装载的时候就被实例化了。

饿汉式和懒汉式区别:

 

饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了,

而懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例。

 

1、线程安全:

饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题,

懒汉式本身是非线程安全的,为了实现线程安全有几种写法,分别是上面的1、2、3,这三种实现在资源加载和性能方面有些区别。

2、资源加载和性能:饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成。

而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要做初始化,如果要做的工作比较多,性能上会有些延迟,之后就和饿汉式一样了。

 

至于1、2、3这三种实现又有些区别,

第1种,在方法调用上加了同步,虽然线程安全了,但是每次都要同步,会影响性能,毕竟99%的情况下是不需要同步的,

第2种,在getInstance中做了两次null检查,确保了只有第一次调用单例的时候才会做同步,这样也是线程安全的,同时避免了每次都同步的性能损耗

第3种,利用了classloader的机制来保证初始化instance时只有一个线程,所以也是线程安全的,同时没有性能损耗,所以一般我倾向于使用这一种。

什么是线程安全?

 

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

或者说:一个类或者程序所提供的接口对于线程来说是原子操作,或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题,那就是线程安全的。

 

单例模式为一个面向对象的应用程序提供了对象惟一的访问点,不管它实现何种功能,整个应用程序都会同享一个实例对象。

 

 

分享到:
评论

相关推荐

    Java学习资料全套.zip

    最新全套Java学习资料打包 最新全套Java学习资料打包 最新全套Java学习资料打包 最新全套Java学习资料打包 最新全套Java学习资料打包 最新全套Java学习资料打包 最新全套Java学习资料打包 最新全套Java...

    java学习路线(鱼皮)

    Java学习路线(鱼皮) Java学习路线(鱼皮)是一条龙版本的学习路线,从入门到入土,旨在帮助学习者快速掌握Java开发的所有知识点。本路线的特点是新、完整、实用、开源、回馈社区、持续更新。 学习路线的主要...

    最全JAVA学习路线一条龙思维导图(附资源链接)PS:程序员鱼皮

    最全JAVA学习路线一条龙思维导图(附资源链接)PS:程序员鱼皮 1. 最新,完整一条龙的大厂 Java 学习路线,从入门到入土 2. 同时适用于想全面学习 / 快速求职的同学,可以根据符号来定制自己的专属学习路线 3. 给出...

    java学习java学习

    java学习java学习java学习java学习java学习java学习

    Java学习入门资料 PPT版本

    ### Java学习入门资料知识点梳理 #### 一、Java语言历史与发展 - **起源与早期发展** - **前身**:Oak(1990年),由James Gosling等人在Sun Microsystems开发。 - **Green项目**:Sun Microsystems于1990年开始...

    Java学习指南第四版下册

    《Java学习指南(第4版)(上、下册)》是畅销Java学习指南的ZUI新版,详细介绍了Java 6和Java 7的语言特性和API。本书全面介绍了Java的基础知识,力图通过完备地介绍Java语言、其类库、编程技术以及术语,从而成为一本...

    java学习心得 java学习心得

    java学习心得java学习心得java学习心得java学习心得

    Java入门1·2·3:一个老鸟的Java学习心得.rar 超清

    《Java入门1·2·3:一个老鸟的Java学习心得》是一本与众不同的Java入门好书。作者以独特的视角,向Java初学者讲述了如何才能真正理解和掌握Java语言。《Java入门1·2·3:一个老鸟的Java学习心得》充分考虑了初学Java...

    JAVA学习JAVA学习

    java学习java学习

    java 学习资料大全

    总之,“Java学习资料大全”应该包含了以上各个领域的教程、示例代码、实践项目和相关书籍,为初学者到高级开发者提供了全面的学习资源。通过深入学习并不断实践,可以成为一名熟练的Java开发者。

    java学习方法及学习总结

    java学习方法及学习总结 java学习方法及学习总结 java学习方法及学习总结

    java 学习路线图-2018最新

    java 学习路线图-2018最新 以有趣和好理解的方式展示Java和Web的内容 设计一些略有挑战的练习 创造一些便于理解和消化知识点的方式,享受这个创造的过程

    java 学习推荐书籍

    java 学习推荐书籍

    JAVA学习资料大全

    JAVA学习资料大全JAVA学习资料大全JAVA学习资料大全

    JAVA学习全套PPT

    【JAVA编程学习】是计算机科学领域的一个重要主题,尤其对于初学者来说,它是一个非常有价值的起点。Java是一种广泛使用的面向对象的编程语言,以其“一次编写,到处运行”的特性而闻名,这得益于Java虚拟机(JVM)...

    30套最实用JAVA学习视频教程合集

    标题《30套最实用JAVA学习视频教程合集》所涉及的知识点主要围绕Java学习资源的汇总。Java作为一门广泛使用的编程语言,在互联网和企业级应用中扮演着重要角色。为了帮助初学者或者已经从事Java开发的程序员快速掌握...

    B站韩顺平老师Java学习路线

    B站韩顺平老师Java学习路线

    良葛格JAVA学习笔记

    而今天,我们要介绍的这份《良葛格JAVA学习笔记》便是一份得到广泛好评,深受学习者喜爱的学习资源。 首先,我们不得不提的是这份笔记的作者——“良葛格”,一个在编程教育界颇具声望的人物。他的这份学习笔记因...

    JAVA学习从150道经典例题突破

    《JAVA学习从150道经典例题突破》这份资源,正是为了满足广大编程初学者这一需求而精心制作的。 本书的编排结构从基础概念入手,逐步向更深层次的内容推进,每一章都围绕着特定的编程主题展开,通过实例帮助学习者...

Global site tag (gtag.js) - Google Analytics