Singleton单例模式的几种创建方法

创建单例类有以下几种方式:

饿汉式

懒汉式(加同步锁的懒汉式、加双重校验锁的懒汉式、防止指令重排优化的懒汉式)

登记式单例模式

静态内部类单例模式

枚举类型的单例模式

 

备注:

其中“枚举类型的单例模式。”最牛逼,可以防止反射调用构造器

 

饿汉式;

public class MyManger {

    private static  MyManger instance=new MyManger();

    private  MyManger() {

    }

    public static MyManger getInstance() {

        return instance;

    }

 

}

 

懒汉式-加同步锁的懒汉式

public class MyManger2 {

    private static MyManger2 instance;

    private MyManger2() {

    }

    public static synchronized MyManger2 getInstance() {

        if(instance==null){

            instance=new MyManger2();

        }

        return instance;

    }

}

 

懒汉式-加双重校验锁的懒汉式

public class MyManger3 {

    private static MyManger3 instance;

    private MyManger3() {

    }

    public static  MyManger3 getInstance() {

        if(instance==null){

            synchronized (MyManger3.class){

                if(instance==null){

                    instance=new MyManger3();

                }

            }

        }

        return instance;

    }

}

 

懒汉式-加双重校验锁&防止指令重排序的懒汉式

public class MyManger3 {

    private static volatile MyManger3 instance;

    private MyManger3() {

    }

    public static  MyManger3 getInstance() {

        if(instance==null){

            synchronized (MyManger3.class){

                if(instance==null){

                    instance=new MyManger3();

                }

            }

        }

        return instance;

    }

}

 

登记式单例模式;

就是将该类名进行登记,每次调用前查询,如果存在,则直接使用;不存在,则进行登记。

public class MyManger4 {

    private static volatile MyManger4 instance;

    private static Map map = new HashMap();

    private MyManger4() {

    }

    public static MyManger4 getInstance(String name) {

        if (null == name) {

            name = MyManger4.class.getName();

            System.out.println("name == null  --- > name == " + name);

        }

        if (null == map.get(name)) {

            try {

                map.put(name, (MyManger4) Class.forName(name).newInstance());

            } catch (InstantiationException e) {

                e.printStackTrace();

            } catch (IllegalAccessException e) {

                e.printStackTrace();

            } catch (ClassNotFoundException e) {

                e.printStackTrace();

            }

        }

        return map.get(name);

    }

}

 

静态内部类单例模式;

public class MyManger5 {

    private static volatile MyManger5 instance;

    private MyManger5() {

    }

    private static class SingletonHolder {

        private static MyManger5 instance = new MyManger5();

    }

    public static MyManger5 getInstance( ) {

        return  SingletonHolder.instance;

    }

}

 

枚举类型的单例模式

在枚举中我们明确了构造方法限制为私有,在我们访问枚举实例时会执行构造方法,同时每个枚举实例都是static final类型的,也就表明只能被实例化一次。在调用构造方法时,我们的单例被实例化。也就是说,因为enum中的实例被保证只会被实例化一次,所以我们的INSTANCE也就会被实例化一次。

public enum MyManger6 {

    INSTANCE;

    private  MyResource instance;

    MyManger6() {

        instance = new MyResource();

    }

    public  MyResource getInstance() {

        return instance;

    }

}

class MyResource {

    public void doMethod() {

        System.out.println("枚举类型的单例类资源");

    }

// getInstance 示例
MyResource myResource=MyManger6.INSTANCE.getInstance();
 

[Singleton单例模式的几种创建方法](https://blog.csdn.net/hl_java/article/details/70148622)
[Singleton单例模式-如何防止JAVA反射对单例类的攻击?](https://blog.csdn.net/hl_java/article/details/71511839)
[Singleton单例模式-如何防止序列化对单例类的攻击?](https://blog.csdn.net/hl_java/article/details/87464951)
[Singleton单例模式-【懒汉式-加双重校验锁&防止指令重排序的懒汉式】实现方案中为什么需要加volatile关键字?](https://blog.csdn.net/hl_java/article/details/89160086)
 

你可能感兴趣的:(java,java,singleton)