7种单例模式

SingletonObject1.java
package com.test.synchonized2;

/**
 * 饿汉模式的单例,缺点:不是懒加载,所以会造成即使没有该类实例没有被使用,
 * 也会有实例被加载出来,会出现资源浪费
 */
public class SingletonObject1 {

    private static SingletonObject1 instance = new SingletonObject1();

    private SingletonObject1() {
        // empty
    }

    public static SingletonObject1 getInstance() {
        return instance;
    }
}
SingletonObject2.java
package com.test.synchonized2;

/**
 * 懒汉模式的单例(懒加载方式),缺点:在多线程环境中调用,可能会出现创建多个实例,
 * 导致不是真正的单例模式
 */
public class SingletonObject2 {

    private static SingletonObject2 instance;

    private SingletonObject2() {
        // empty
    }

    public static SingletonObject2 getInstance() {
        if (instance == null) {
            instance = new SingletonObject2();
        }
        return instance;
    }
}
SingletonObject3.java
package com.test.synchonized2;

/**
 * 同步方法+懒汉模式的单例(懒加载),缺陷:能解决多线程环境中懒加载造成的多个实例问题,
 * 但是也同样导致获取实例方法变为了“串行化”,在多线程环境中获取单例速度变慢,影响性能
 */
public class SingletonObject3 {

    private static SingletonObject3 instance;

    private SingletonObject3() {
        // empty
    }

    public synchronized static SingletonObject3 getInstance() {
        if (instance == null) {
            instance = new SingletonObject3();
        }
        return instance;
    }
}
SingletonObject4.java
package com.test.synchonized2;

/**
 * 同步方法+双重验证(double check)的懒汉单例模式(懒加载)
 * 缺陷:即使进行了double check ,但是因为没有使用volatile修饰,
 * 所以无法保证可见性和有序性:volatile关键字可以保证【可见性】和【有序性】
 * 因为没有保证有序性,所以可能出现空指针异常
 */
public class SingletonObject4 {

    private static SingletonObject4 instance;

    private Object obj1;

    private Object obj2;

    private SingletonObject4() {
        // empty
        /**
         * 因为没有保证可见性和有序性,所以在初始化过程中会出现重排序,
         * instance 已经创建好了,但是 obj1和obj2还没创建好,
         * 第二个线程走到过程①的时候,以为instance创建好了,所以就返回了 instance 实例
         * 但是调用到instance的 obj1或者obj2引用类型的属性进行操作时候就可能出现 空指针异常
         */
        obj1 = new Object();
        obj2 = new Object();
    }

    public static SingletonObject4 getInstance() {
        if (instance == null) { // ①
            synchronized (SingletonObject4.class) {
                if (instance == null) {
                    instance = new SingletonObject4();
                }
            }
        }
        return instance;
    }
}

 

SingletonObject5.java
package com.test.synchonized2;

public class SingletonObject5 {

    private static volatile SingletonObject5 instance;

    private SingletonObject5() {
        // empty
    }

    public static SingletonObject5 getInstance() {
        if (instance == null) {
            synchronized (SingletonObject5.class) {
                if (instance == null) {
                    instance = new SingletonObject5();
                }
            }
        }
        return instance;
    }
}

 

SingletonObject6.java
package com.test.synchonized2;

/**
 * 利用的策略:静态类只会被JVM创建一次
 */
public class SingletonObject6 {

    private SingletonObject6() {
        // empty
    }

    private static class InstanceHolder{
        private static final SingletonObject6 instance = new SingletonObject6();
    }

    public static SingletonObject6 getInstance() {
        return InstanceHolder.instance;
    }

}

 

SingletonObject7.java
package com.test.synchonized2;

/**
 * 最好的单例模式需要满足三点要求:
 * ① 懒加载模式
 * ② 在多线程环境中实例也是只会被创建一次,实现单例
 * ③ 在多线程环境中获取单例实例时,性能与在单线程环境中使用一致,不存在“串行化”或者“阻塞问题”
 */
public class SingletonObject7 {

    private SingletonObject7() {
        // empty
    }

    /**
     * 利用枚举两个特性实现单例模式:
     * ① 枚举类是线程安全的
     * ② 枚举的构造方法只会被装载一次
     */
    private enum Singleton {
        INSTANCE;

        private final SingletonObject7 instance;

        Singleton() {
            instance = new SingletonObject7();
        }

        public SingletonObject7 getInstance() {
            return instance;
        }
    }

    public static SingletonObject7 getInstance() {
        return Singleton.INSTANCE.getInstance();
    }

    public static void main(String[] args) {
        for (int i = 0; i <100 ; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(SingletonObject7.getInstance());
                }
            }).start();
        }
    }
}

 

 

 

你可能感兴趣的:(7种单例模式)