设计模式(java版)——创建型——单例模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37776094/article/details/89632665

项目源码已提交github:https://github.com/ckl001/designPattem_java

创建型

单例模式

1.饿汉模式
2.懒汉模式
3.内部类模式
4.枚举模式

破坏单例模式
1.序列化
2.反射

package com.Ljava.design.pattem.creational.singleton;

/**
 * @Auther 20173
 * @Date 2019-4-8 11:48
 * @Des 单例:枚举 推荐使用
 **/
public enum EnumInstance {

    INSTANCE{
        protected void prinTest() {
            System.out.println("print test!");
        }
    };

    protected abstract void prinTest();

    public static EnumInstance getInstance(){
        return INSTANCE;
    }

    public Object data;
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }}

package com.Ljava.design.pattem.creational.singleton;

import java.io.Serializable;

/**
 * @Auther 20173
 * @Date 2019-4-8 11:48
 * @Des 单例:饿汉模式
 **/
public class HungrySingleton implements Serializable {
    private final static HungrySingleton hungrySingleton;
    static {
        hungrySingleton = new HungrySingleton();
    }

    //防止反射破坏单例模式
    private HungrySingleton(){
        if(hungrySingleton != null){
            throw new RuntimeException("单例模式禁止反射调用!");
        }
    }

    public static HungrySingleton getInstance(){
        return hungrySingleton;
    }

    // 解决对象反序列化;
    // 反序列化的时候会进行浅拷贝则返回的对象是新的对象;
    // Singleton中定义readResolve方法,并在该方法中指定要返回的对象的生成策略,就可以防止单例被破坏。
    private Object readResolve(){
        System.out.println("调用了readResolve方法!");
        return hungrySingleton;
    }

}

package com.Ljava.design.pattem.creational.singleton;

/**
 * @Auther 20173
 * @Date 2019-4-8 14:06
 * @Des 单例: 懒汉模式--双重锁
 **/
public class LazyDoubleCheckSingleton {
    // volatile 防止指令重排,内存可见性
    private volatile static LazyDoubleCheckSingleton lazyDoubleCheckSingleton = null;
    public LazyDoubleCheckSingleton() {
    }

    public static LazyDoubleCheckSingleton getInstance(){
        if(lazyDoubleCheckSingleton == null){
            synchronized (LazyDoubleCheckSingleton.class){
                if(lazyDoubleCheckSingleton == null){
                    // 1.分配内存给这个对象
                    // 2.初始化这个对象
                    // 3.设置lazyDoubleCheckSingleton 指向刚分配的内存地址
                    // 指令重排:第二步跟第三步的顺序调换
                    lazyDoubleCheckSingleton = new LazyDoubleCheckSingleton();
                }
            }
        }
        return lazyDoubleCheckSingleton;
    }
}
package com.Ljava.design.pattem.creational.singleton;

/**
 * @Auther 20173
 * @Date 2019-4-8 14:34
 * @Des 单例模式: 静态内部类
 **/
public class StaticInnerClassSingleton {

    //内部类
    private static class InnerClass{
        private static StaticInnerClassSingleton staticInnerClassSingleton = new StaticInnerClassSingleton();
    }

    private static StaticInnerClassSingleton getInstance(){
        return InnerClass.staticInnerClassSingleton;
    }

    //防止反射调用
    private StaticInnerClassSingleton(){
        if(InnerClass.staticInnerClassSingleton != null){
            throw new RuntimeException("单例构造器禁止反射调用");
        }
    }
}

package com.Ljava.design.pattem.creational.singleton;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @Auther 20173
 * @Date 2019-4-8 11:52
 * @Des 测试类
 **/
public class Test {

    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        //饿汉模式 对象序列化
//        HungrySingleton instance = HungrySingleton.getInstance();
//        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\MyCode\\designPattem\\src\\main\\java\\com\\Ljava\\design\\pattem\\creational\\singleton\\instance_file.txt"));
//        oos.writeObject(instance);
//        File file = new File("D:\\MyCode\\designPattem\\src\\main\\java\\com\\Ljava\\design\\pattem\\creational\\singleton\\instance_file.txt");
//        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
//        HungrySingleton newInstance = (HungrySingleton) ois.readObject();
//        System.out.println(instance);
//        System.out.println(newInstance);

        //饿汉模式 反射破解单例模式
//        Class objectClass = HungrySingleton.class;
//        Constructor constructor = objectClass.getDeclaredConstructor();
//        constructor.setAccessible(true);
//        HungrySingleton instanceClass = HungrySingleton.getInstance();
//        HungrySingleton newInstanceClass = (HungrySingleton) constructor.newInstance();
//        System.out.println(instanceClass);
//        System.out.println(newInstanceClass);

        EnumInstance enumInstance = EnumInstance.getInstance();
        enumInstance.prinTest();


    }
}

猜你喜欢

转载自blog.csdn.net/m0_37776094/article/details/89632665