1、手写单例模式
1-1、手写单例模式-概述
1、手写单例模式-概述: 1-1、使用一个私有构造函数、一个私有静态变量以及一个公有静态函数来实现。 1-2、私有构造函数保证了不能通过构造函数来创建对象实例,只能通过公有静态函数返回唯一的私有静态变量。2、手写单例模式-实现方式: 2-1、懒汉式-线程不安全 2-2、饿汉式-线程安全 2-3、懒汉式-线程安全 2-4、双重校验锁-线程安全 2-5、静态内部类实现 2-6、枚举实现 ---推荐使用[!!!]
1-2、手写单例模式-Demo
1-2-1、饿汉式:
/*** 饿汉式:静态常量-在类加载的时候就创建实例化*/public class Singleton{ private final static Singleton singleton = new Singleton()//final static修饰 private Singleton(){} //构造器,private修饰 public static Singleton getInstance(){ // static修饰, 静态方法返回实例 return singleton; }}/*** 饿汉式:静态代码块方式实现*/public class Singleton{ private final static Singleton singleton;//final static修饰 static { //静态代码块-类加载时就启动,只加载一次 instance = new Singleton(); } private Singleton(){} //构造器,private修饰 public static Singleton getInstance(){ // static修饰, 静态方法返回实例 return singleton; }}/*** 饿汉式:双重检查方式,线程安全,延迟加载,效率较高*/public class Singleton{ private static volatile Singleton singleton;//volatile修饰 private Singleton(){} //构造器,private修饰 public static Singleton getInstance(){ // static修饰, 静态方法返回实例 if(singleton == null){ synchronized(Singleton.class){ //synchronized if(singleton == null){ singleton = new Singleton(); } } } return singleton; }}/*** 饿汉式:静态内部类方式,JVM帮助我们保证了线程安全性*/public class Singleton{ private Singleton{} // 创建一个静态内部类,在静态内部类中去实例化对象 private static class SingletonInstance{ private static final Singleton singleton = new Singleton(); } public static Singleton getInstance(){ return SingletonInstance.singleton; }}/*** 静态内部类方法 创建单例模式,可能存在反射攻击或这反序列化攻击,如:反射攻击*/public class Singleton{ private Singleton{} // 创建一个静态内部类,在静态内部类中去实例化对象 private static class SingletonInstance{ private static final Singleton singleton = new Singleton(); } public static Singleton getInstance(){ return SingletonInstance.singleton; } public static void main(String[] args) throws Exception { Singleton singleton = Singleton.getInstance(); Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor(); constructor.setAccessible(true); Singleton newSingleton = constructor.newInstance(); System.out.println(singleton == newSingleton); //运行结果是:false }}/*** 静态内部类方法 创建单例模式,可能存在反射攻击或这反序列化攻击,如:反序列化攻击 序列化反序列化依赖jar包:org.apche.commons.commons-langxxx.jar Singleton单例类实现java.io.Serializable接口*/public class Singleton implements Serializable{ //定义一个静态内部类 private static class SingletonHanlder{ private static Singleton singleton = new Singleton(); } private Singleton(){} private static Singleton getInstance(){ return SingletonHandler.singleton; } public static void main(String[] args) { Singleton instance = Singleton.getInstance(); byte[] serialize = SerializationUtils.serialize(singleton); Singleton newInstance = SerializationUtils.deserialize(serialize); System.out.println(singleton == newInstance); //返回结果,false,两个实例不是同一个。 }}/*** 枚举实现,可避免多线程同步问题,还能防止反序列化重新创建新的对象问题*/public enum Singleton{ singleton; //自定义方法,比如:work public void work{ System.out.println("doWorking"); } public static void main(String[] args){ Singleton.singleton.work();//输出结果:doWorking }}
1-2-2、懒汉式:在真正需要的时候再去创建实例
/*** 懒汉式:安全写法, volatile修饰实例,防止指令重排情况 synchrinized锁住类实例,双重校验方式*/public class Singleton{ private static volatile Singleton singleton; privete Singleton{} public static Singleton getInstance(){ if(singleton == null){ synchronized(Singleton.class){ if(singleton == null){ singleton = new Singleton(); } } } return singleton; }}
1-2-3、单例模式-实现方式-总结
