1)概念:它的核心结构中包含一个被称为单例的特殊类。
2)特点:
1.单例类只能有一个实例。
2.单例类必须自己创建自己的唯一实例。
3.单例类必须给所有其他对象提供一个实例。
3)实现单例
1.饿汉式单例(线程安全)
在类加载时就完成了初始化。饿汉式单例在类初始化时就创建好了一个静态对象供外部使用,除非系统重启,这个对象不会改变,所以本身就是线程安全。
package com.ual.singleton; public class Singleton1 { /*饿汉式单例1*/ private Singleton1(){}//提供私有构造方法 private static Singleton1 single=new Singleton1();//提供静态单例对象 public static Singleton1 getInstance(){ return single; } }
package com.ual.singleton; public class Singleton2 { /*饿汉式单例2*/ private Singleton2(){} private static Singleton2 singleton2=null; //静态代码块 static { singleton2=new Singleton2(); } public static Singleton2 getInstance(){ return singleton2; } }
2.懒汉式单例(延迟加载形式)
package com.ual.singleton; public class Singleton3 { /*懒汉式单例,非线程安全*/ private Singleton3(){} private static Singleton3 singleton3=null; public static Singleton3 getInstance(){ if(singleton3==null){ singleton3=new Singleton3(); } return singleton3; } }
package com.ual.singleton; public class Singleton4 { /*懒汉式单例,线程安全,双重检索*/ private Singleton4(){} private static Singleton4 singleton4 = null; public static Singleton4 getInstance(){ //双重检索 if(singleton4==null){ synchronized (Singleton4.class){ if(singleton4==null){ return singleton4 } } } return singleton4; } }
package com.ual.singleton; public class Singleton5 { private Singleton5(){} //静态内部类 //外部类被加载,内部类不会被加载,除非主动是使用 private static class InsideClass{ private static Singleton5 singleton5=new Singleton5(); } public static Singleton5 getInstance(){ return InsideClass.singleton5; } }
优点:1.在内存中只有一个实例,减少了内存开销,尤其是频繁的创建销毁对象。
2.避免对资源的多重占用(比如写某文件的操作)
缺点:扩展很困难。
应用场景:1.web中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
2.创建的一个对象需要消耗的资源过多,比如IO,数据库的连接。