单列设计模式

单列中的四种实现方式

方式一:普通的饿汉式和懒汉式单例模式

三部曲:java

(1)私有化构造方法
(2)私有化静态本类对象做为属性
(3)提供公有静态方法获取本类对象

 1.普通的饿汉式(静态的内部)安全

public class Client {
    public static void main(String[] args) {
        Singleton.getInstance();
    }

    static class Singleton {
        private static final Singleton instance = new Singleton();

        private Singleton(){}

        public static Singleton getInstance(){
            return  instance;
        }

    }
}

2.饿汉式静态代码块单例模式并发

//饿汉式静态代码块单例模式
public class HungryStaticSingleton {
    private static final HungryStaticSingleton instance;

    static {
        instance = new HungryStaticSingleton();
    }

    private HungryStaticSingleton(){}

    public static HungryStaticSingleton getInstance(){
        return  instance;
    }
}

3.饿汉式静态代码块单例模式ide

/**
 * 优势:执行效率高,性能高,没有任何的锁
 * 缺点:某些状况下,可能会形成内存浪费
 */
//饿汉式静态代码块单例模式
public class HungrySingleton {

    private static final HungrySingleton instance = new HungrySingleton();

    private HungrySingleton(){}

    public static HungrySingleton getInstance(){
        return  instance;
    }
}

二:懒汉式

1.懒汉式单例模式在外部须要使用的时候才进行实例化,这种是线程不安全的,若是多个线程同时并发访问,假设多个线程同时都进入到了 if(instance == null){}条件判断里面,那么就会同时建立多个对象。性能

/**
 * 优势:节省了内存,线程安全
 * 缺点:性能低
 */
//懒汉式单例模式在外部须要使用的时候才进行实例化
public class LazySimpleSingletion {
    //静态块,公共内存区域
    private static LazySimpleSingletion instance;

    private LazySimpleSingletion(){}

    public synchronized static LazySimpleSingletion getInstance(){
        if(instance == null){
            instance = new LazySimpleSingletion();
        }
        return instance;
    }
}

2.单次检查机制(使用类锁),这种也是有缺点的,使用的 synchronized 关键字,严重的影响了性能.this

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

3.利用双重检查机制(DCL) ,保证了线程的安全spa

/**
 * 优势:性能高了,线程安全了
 * 缺点:可读性难度加大,不够优雅
 */
public class LazyDoubleCheckSingleton {
    private volatile static LazyDoubleCheckSingleton instance;
    private LazyDoubleCheckSingleton(){}

    public static LazyDoubleCheckSingleton getInstance(){
        //检查是否要阻塞
        if (instance == null) {
            synchronized (LazyDoubleCheckSingleton.class) {
                //检查是否要从新建立实例
                if (instance == null) {
                    instance = new LazyDoubleCheckSingleton();
                    //指令重排序的问题
                }
            }
        }
        return instance;
    }
}

4.自认为史上最牛的单例模式的实现方式 (这里有个技术上的高深的点技术基础点,说到底仍是技术的基础和本质)----->>>> 利用了Java自己语法特色,内部类默认不加载线程

/*
  ClassPath : LazyStaticInnerClassSingleton.class
              LazyStaticInnerClassSingleton$LazyHolder.class
   优势:写法优雅,利用了Java自己语法特色,性能高,避免了内存浪费,不能被反射破坏
   缺点:不优雅
 */
//这种形式兼顾饿汉式单例模式的内存浪费问题和synchronized的性能问题
//完美地屏蔽了这两个缺点
//自认为史上最牛的单例模式的实现方式
public class LazyStaticInnerClassSingleton {
    //使用LazyInnerClassGeneral的时候,默认会先初始化内部类
    //若是没使用,则内部类是不加载的
    private LazyStaticInnerClassSingleton(){
        if(LazyHolder.INSTANCE != null){
            throw new RuntimeException("不容许建立多个实例");
        }
    }
    //每个关键字都不是多余的,static是为了使单例的空间共享,保证这个方法不会被重写、重载
    private static LazyStaticInnerClassSingleton getInstance(){
        //在返回结果之前,必定会先加载内部类
        return LazyHolder.INSTANCE;
    }

    //利用了Java自己语法特色,内部类默认不加载
    private static class LazyHolder{
        private static final LazyStaticInnerClassSingleton INSTANCE = new LazyStaticInnerClassSingleton();
    }

}

5.枚举法code

public enum EnumSingleton {
    INSTANCE;

    private Object data;

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public static EnumSingleton getInstance(){return INSTANCE;}
}

 6.序列化一个单列对象对象

import java.io.Serializable;

public class SeriableSingleton implements Serializable {


    //序列化
    //把内存中对象的状态转换为字节码的形式
    //把字节码经过IO输出流,写到磁盘上
    //永久保存下来,持久化

    //反序列化
    //将持久化的字节码内容,经过IO输入流读到内存中来
    //转化成一个Java对象


    public  final static SeriableSingleton INSTANCE = new SeriableSingleton();
    private SeriableSingleton(){}

    public static SeriableSingleton getInstance(){
        return INSTANCE;
    }

    private Object readResolve(){ return INSTANCE;}

}

 

7.手动建立一个单列对象(根据类名来建立)

public class ContainerSingleton {

    private ContainerSingleton(){}

    private static Map<String,Object> ioc = new ConcurrentHashMap<String, Object>();

    public static Object getInstance(String className){
        Object instance = null;
        if(!ioc.containsKey(className)){
            try {
                instance = Class.forName(className).newInstance();
                ioc.put(className, instance);
            }catch (Exception e){
                e.printStackTrace();
            }
            return instance;
        }else{
            return ioc.get(className);
        }
    }
}

8.ThreadLocal设置单列

public class ThreadLocalSingleton {
    private static final ThreadLocal<ThreadLocalSingleton> threadLocaLInstance =
            new ThreadLocal<ThreadLocalSingleton>(){
                @Override
                protected ThreadLocalSingleton initialValue() {
                    return new ThreadLocalSingleton();
                }
            };

    private ThreadLocalSingleton(){}

    public static ThreadLocalSingleton getInstance(){
        return threadLocaLInstance.get();
    }
}
相关文章
相关标签/搜索