设计模式之单例模式(1)

单例模式:确保一个类只有一个实例,并提供全局访问点.

1 饿汉式(线程安全)

package com.oo.singleton;

/**
 * 饿汉式(线程安全)
 *
 * @author xyy
 * @create 2017-06-15 16:25
 **/
public class Singleton0 {

    /**
     * 在静态初始化的时候创建单件,确保了线程安全
     */
    private static Singleton0 singleton0 = new Singleton0();

    private Singleton0() {

    }

    /**
     * 已经有实例的直接使用
     * @return
     */
    public static Singleton0 getInstance() {
        return singleton0;
    }

}

2.懒汉式(线程不安全)

package com.oo.singleton;

/**
 * 懒汉式(线程不安全)
 * @author xyy
 * @create 2017-06-15 16:06
 **/
public class Singleton1 {
    /**
     * 利用一个静态变量记录Singleton1的唯一实例
     */
    private static Singleton1 singleton1;

    /**
     * 把构造器声明为私有的,只有SingLeon1的内部才可以调用构造器
     */
    private Singleton1() {

    }

    public static Singleton1 getInstance() {
        //null.表明还没有创建实例
        if (singleton1 == null) {
            singleton1 = new Singleton1();
        }
        //不为null,直接返回
        return singleton1;
    }


    public static void main(String[] args) {
        Singleton1 singleton1 = Singleton1.getInstance();
        Singleton1 singleton2 = Singleton1.getInstance();
        System.out.println(singleton1 == singleton2);
        System.out.println(singleton1.equals(singleton2));


    }
}

3.懒汉式(线程安全之synchronized关键字)

package com.oo.singleton;

/**
 * 懒汉式(线程安全之synchronized关键字)
 *
 * @author xyy
 * @create 2017-06-15 16:17
 **/
public class Singleton2 {

    private   static Singleton2 singleton2;


    private Singleton2() {

    }

    /**
     * 1.降低性能
     * 2.通过增加synchronized关键字,确保每个线程在进入这个方法之前.要等候别的线程离开这个方法
     * 3.其实只有第一次执行这个方法才需要同步,以后再次调用就不需要了,同步是一个累赘
     * @return
     */
    public  static synchronized Singleton2 getInstance() {
        if (singleton2 == null) {
            return new Singleton2();
        }
        return singleton2;
    }



}

4.懒汉式(线程安全之双重检查锁)

package com.oo.singleton;

/**
 * 懒汉式(线程安全之双重检查锁)
 *不适用与1.4及其下版本
 * @author xyy
 * @create 2017-06-15 16:22
 **/
public class Singleton3 {

    /**
     * volatile关键字singleton3被初始化后,多个线程正确的处理singleton3;
     */
    private volatile static Singleton3 singleton3;

    private Singleton3() {

    }

    /**
     * 1.首先检查实例是否创建了,如果尚未创建,才进行同步,这样一来,只有第一次创建实例时会同步
     *
     * @return
     */
    public static Singleton3 getInstance() {
        //1.检查实例,如果不存在,就进入同步区块
        if (singleton3 == null) {
            //2.只有第一次才执行这里的代码
            synchronized (Singleton3.class) {
                //3.进入区块后,在检查一次,如果仍为空,创建实例
                if (singleton3 == null) {
                    return new Singleton3();
                }
            }
        }
        return singleton3;

    }

}

5.静态内部类实现单例(线程安全)

package com.oo.singleton;

/**
 * 静态内部类实现单例(线程安全)
 *
 * @author xyy
 * @create 2017-06-15 16:49
 **/
public class Singleton4 {

    /**
     *1.类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例;
     * 2.没有绑定关系,而且只有被调用到时才会装载,从而实现了延迟加载。
     */
    private Singleton4() {
    }

    private static class SingletonHolder {

        /**
         * 静态初始化器,由JVM来保证线程安全
         */
        private static Singleton4 singleton4 = new Singleton4();

        public static Singleton4 getInstance() {
            return SingletonHolder.singleton4;
        }

    }


    public static void main(String[] args) {
        /**
         * 1.当getInstance方法第一次被调用的时候,它第一次读取SingletonHolder.instance,导致SingletonHolder类得到初始化;
         * 2.而这个类在装载并被初始化的时候,会初始化它的静态域,从而创建Singleton的实例,
         * 3.由于是静态的域,因此只会在虚拟机装载类的时候初始化一次,并由虚拟机来保证它的线程安全性
         */
        Singleton4 singleton41 = Singleton4.SingletonHolder.getInstance();
        Singleton4 singleton42 = Singleton4.SingletonHolder.getInstance();
        System.out.println(singleton41 == singleton42);
        System.out.println(singleton41.equals(singleton42));
    }
}

6.单例和枚举

package com.oo.singleton;

/**
 * 1.单例和枚举
 * 2.参考(http://www.cnblogs.com/java-my-life/archive/2012/03/31/2425631.html)
 * Created by 14258 on 2017/6/15.
 */
public enum Singleton5 {
    /**
     * 定义一个枚举的元素,它就代表了Singleton的一个实例。
     */
    instance;

    public void getInstance() {
        //功能处理
    }


    public static void main(String[] args) {

    }
}

参考:1.《JAVA与模式》之单例模式

猜你喜欢

转载自blog.csdn.net/qq_25385555/article/details/73294302
今日推荐