设计模式之单列模式

单列模式:

概念:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

1、单列类只能有一个实列

2、单列类必须自己创建自己的实列

3、单列类必须提供给所有其他对象获得该实列的方法

单列模式——饿汉式:

优点:线程安全、执行效率高

缺点:类加载时就初始化,浪费内存,容易产生垃圾对象(类加载时创建了对象,又没有调用方法获取实列)

/**
 * 单列模式——饿汉式
 * @author ypf
 *  
 */
public class Singleton1 {
    private static Singleton1 instance = new Singleton1();
    //构造方法私有化
    private Singleton1() {
        
    }
    public static Singleton1 getInstance() {return instance;
    }
}

单列模式——懒汉式:

优点:第一次使用时才初始化,避免了内存浪费;

缺点:线程不安全,不支持多线程;

/**
 *     单列模式——懒汉式
 * @author ypf
 *
 */
public class Singleton2 {
    private static Singleton2 instance;
    //构造方法私有化
    private Singleton2() {
    }
    public static Singleton2 getInstance() {
        if(instance == null) {
            instance = new Singleton2();
        }
        return instance;
    }
}

单列模式——懒汉式(简单优化):

优点:实现了lazy-load(懒加载),第一次使用时才初始化,避免了内存浪费,线程安全;

缺点:执行效率低

/**
 *     单列模式——懒汉式(简单优化)
 * @author ypf
 *
 */
public class Singleton3 {
    private static Singleton3 instance;
    //构造方法私有化
    private Singleton3() {
    }
  //对方法加synchronized关键字
public synchronized static Singleton3 getInstance() { if(instance == null) { instance = new Singleton3();

}
return instance; } }

单列模式——双重检测锁式:

优点:第一次使用时才初始化,避免了内存浪费,线程安全,在多线程情况下也能保持高性能;

缺点 : 实现较复杂

在本次线程内,当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一个寄存器中;以后再取变量值时,就直接从寄存器中取值;

/**
 *     单列模式——双重检测锁式
 * @author ypf
 *
 */
public class Singleton4 {
    //给变量加volatile关键字,为了让编译器在使用这个变量时必须每次都重新读取这个变量的值,而不是使用保存在寄存器里的备份
    private static volatile Singleton4 instance;
    //构造方法私有化
    private Singleton4() {
    }
    public synchronized static Singleton4 getInstance() {
        //避免每次都获取锁
        if(instance == null) {
            synchronized (Singleton4.class) {
                if(instance == null) {
                    instance = new Singleton4();
                }
            }
        }
        return instance;
    }
}

单列模式——静态内部类式:

优点:线程安全、延迟加载、可以达到与双重检测锁一样的效果,但实现更简单,这种方式只适用于静态域的情况。

/**
 *     单列模式——静态内部类
 * @author ypf
 *
 */
public class Singleton5 {
    
    private static class getSingleton{
        private static final Singleton5 INSTANCE = new Singleton5();
    }
    //构造方法私有化
    private Singleton5() {
    }
    public static Singleton5 getInstance() {
        return getSingleton.INSTANCE;
    }
}

单列模式——枚举式:

优点:避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。

刚开始看到枚举式是这样的,

/**
 *     单列模式——枚举
 * @author ypf
 *
 */
public enum Singleton6 {
    INSTANCE;
    
    public void anyMethod(){
        
    } 
}

测试一下:

/**
 *     单列模式——枚举
 * @author ypf
 *
 */
public enum Singleton6 {
    INSTANCE;
    private Singleton6() {
        System.out.println("构造方法");
    }
    public void anyMethod(){
        System.out.println(123);
    } 
}

 测试代码:

 

public class TestSingleton {
    public static void main(String[] args) {
        Singleton6 instance = Singleton6.INSTANCE;
        Singleton6 instance1 = Singleton6.INSTANCE;
        Singleton6 instance2 = Singleton6.INSTANCE;
        Singleton6 instance3 = Singleton6.INSTANCE;
        
        System.out.println(instance.hashCode());
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
        instance.anyMethod();
        instance1.anyMethod();
        instance2.anyMethod();
        instance3.anyMethod();
    }
}

 

效果展示:

 

可以看到构造方法只执行了一次,即是同一个实列

 

posted @ 2019-05-04 22:05  LikFre  阅读(264)  评论(0编辑  收藏  举报