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、单例模式-实现方式-总结