IntelliJ IDEA教程 joomla x86 db2 odbc Minjs Validator vue表单 vue开发教程 jq第一个子元素 matlab停止运行命令 python字典类型 python免费教程 python插件 python运行 java入门级教程 java的数据结构 java读取文件数据 java框架学习 java创建对象 linuxtar命令 php开发实例 java游戏开发教程 p2pover 销售单打印软件 listpreference 系统维护工具 密码翻译 bilibili硬币 视频旋转软件 vbs代码表白 淘宝店铺会员 打开组策略的命令 c4d克隆 pr怎么旋转视频画面 ppt去掉背景音乐 电子海图 environment 保卫萝卜攻略沙漠7 cts测试
当前位置: 首页 > 学习教程  > 编程语言

玩转单例模式

2020/8/31 14:26:01 文章标签:

饿汉式单例

//饿汉式单例
public class Hungry {
    private Hungry() {
    }
    private final static Hungry HUNGRY = new Hungry();
    public static Hungry getInstance() {
        return HUNGRY;
    }
}

懒汉式单例

//懒汉式
public class LazyMan {
    private LazyMan() {
    }
    private static LazyMan lazyMan;
    public static  LazyMan getInstance() {
        if (lazyMan == null) {
            lazyMan = new LazyMan();
        } 
        return lazyMan;
    }
}

DCL懒汉式(双重检测)

//DCL懒汉式
public class LazyMan {
    private LazyMan() {
        System.out.println(Thread.currentThread().getName()+"启动");
    }
    private volatile static LazyMan lazyMan;
    //双重检测模式的 懒汉式单例  DCL懒汉式
    public static LazyMan getInstance() {
        if (lazyMan == null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    lazyMan = new LazyMan();//如果不加 volatile 不是一个原子性操作
                    /*
                    * 1.分配内存空间
                    * 2.执行构造方法,初始化对象
                    * 3.吧这个对象指向这个空间
                    * */
                }
            }
        }

        return lazyMan;
    }
//多线程并发
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                lazyMan.getInstance();
            }).start();
        }
    }
}

反射破解

//DCL懒汉式
public class LazyMan {
    private LazyMan() {
        System.out.println(Thread.currentThread().getName()+"启动");
    }
    private volatile static LazyMan lazyMan;
    //双重检测模式的 懒汉式单例  DCL懒汉式
    public static LazyMan getInstance() {
        if (lazyMan == null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    lazyMan = new LazyMan();//如果不加 volatile 不是一个原子性操作
                    /*
                    * 1.分配内存空间
                    * 2.执行构造方法,初始化对象
                    * 3.吧这个对象指向这个空间
                    * */
                }
            }
        }

        return lazyMan;
    }
//反射破解
    public static void main(String[] args) throws Exception {
        LazyMan instance = LazyMan.getInstance();
        Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);
        LazyMan lazyMan = declaredConstructor.newInstance();
        System.out.println(instance);
        System.out.println(lazyMan);
    }
}

防止反射破坏(三重检测)

//DCL懒汉式
public class LazyMan {
    private LazyMan() {
        synchronized (LazyMan.class) {
            if (lazyMan != null) {
                throw new RuntimeException("不要试图使用反射破坏");
            }
        }
        System.out.println(Thread.currentThread().getName()+"启动");
    }
    private volatile static LazyMan lazyMan;
    //双重检测模式的 懒汉式单例  DCL懒汉式
    public static LazyMan getInstance() {
        if (lazyMan == null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    lazyMan = new LazyMan();//如果不加 volatile 不是一个原子性操作
                    /*
                    * 1.分配内存空间
                    * 2.执行构造方法,初始化对象
                    * 3.吧这个对象指向这个空间
                    * */
                }
            }
        }
        return lazyMan;
    }
//反射破解
    public static void main(String[] args) throws Exception {
        LazyMan instance = LazyMan.getInstance();
        Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);
        LazyMan lazyMan = declaredConstructor.newInstance();
        System.out.println(instance);
        System.out.println(lazyMan);
    }
}

防止多层反射设置隐藏变量

//DCL懒汉式
public class LazyMan {
    private static boolean ceshi = false;
    private LazyMan() {
        synchronized (LazyMan.class) {
            if (ceshi == false) {
                ceshi = true;
            } else {
                throw new RuntimeException("不要试图使用反射破坏");
            }
        }
        System.out.println(Thread.currentThread().getName()+"启动");
    }
    private volatile static LazyMan lazyMan;
    //双重检测模式的 懒汉式单例  DCL懒汉式
    public static LazyMan getInstance() {
        if (lazyMan == null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    lazyMan = new LazyMan();//如果不加 volatile 不是一个原子性操作
                    /*
                    * 1.分配内存空间
                    * 2.执行构造方法,初始化对象
                    * 3.吧这个对象指向这个空间
                    * */
                }
            }
        }

        return lazyMan;
    }
//反射破解
    public static void main(String[] args) throws Exception {
        LazyMan instance = LazyMan.getInstance();
        Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);
        LazyMan lazyMan = declaredConstructor.newInstance();
        System.out.println(instance);
        System.out.println(lazyMan);
    }
}

通过反编译获取隐藏变量继续破解

//DCL懒汉式
public class LazyMan {
    private static boolean ceshi = false;
    private LazyMan() {
        synchronized (LazyMan.class) {
            if (ceshi == false) {
                ceshi = true;
            } else {
                throw new RuntimeException("不要试图使用反射破坏");
            }
        }
        System.out.println(Thread.currentThread().getName()+"启动");
    }
    private volatile static LazyMan lazyMan;
    //双重检测模式的 懒汉式单例  DCL懒汉式
    public static LazyMan getInstance() {
        if (lazyMan == null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    lazyMan = new LazyMan();//如果不加 volatile 不是一个原子性操作
                    /*
                    * 1.分配内存空间
                    * 2.执行构造方法,初始化对象
                    * 3.吧这个对象指向这个空间
                    * */
                }
            }
        }

        return lazyMan;
    }
//反射破解
    public static void main(String[] args) throws Exception {
        LazyMan instance = LazyMan.getInstance();
        //通过反编译获取隐藏变量名
        Field ceshi = LazyMan.class.getDeclaredField("ceshi");
        ceshi.setAccessible(true);
        ceshi.set(instance, false);
        Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);
        LazyMan lazyMan = declaredConstructor.newInstance();
        System.out.println(instance);
        System.out.println(lazyMan);
    }
}

枚举单例无法反射创建

//枚举本身也是一个类,是一个class类
public enum  EnumSingle {
    INSTANCE;

    public EnumSingle getInstance() {
        return INSTANCE;
    }
}

class Test {
    public static void main(String[] args) throws Exception {
        EnumSingle instance1 = EnumSingle.INSTANCE;
        Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(String.class,int.class);
        declaredConstructor.setAccessible(true);
        EnumSingle enumSingle = declaredConstructor.newInstance();
        System.out.println(enumSingle);
        System.out.println(instance1);

    }
}


本文链接: http://www.dtmao.cc/news_show_150214.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?