设计模式day2-单例

只能存在一个对象实例

八种写法:

考虑方面 :资源使用、线程安全、效率
推荐使用:双重检查、静态内部类、枚举
一定条件下推荐使用:饿汉式
使用场景:频繁的创建和销毁对象;创建对象时耗时过多或耗费资源过多;工具类、频繁访问数据库或文件

1.饿汉式(静态常量)

/*
1.构造函数私有化
2.类内部创建对象
3.对外暴露一个静态的公共方法 getInstance
优点:类加载的时候就完成实例化,避免线程同步问题
缺点:从未使用的情况,会造成内存的浪费
确定单例一定会被用到,也推荐使用
*/
public class Singlenton1 {
    //构造函数私有化
    private Singlenton1(){}
    //静态变量
    private static final Singlenton1 instance= new Singlenton1();
    //静态公共方法
    public static Singlenton1 getInstance(){
        return  instance;
    }
}

2.饿汉式(静态代码块)

/*
静态代码块
优缺点同上
确定单例一定会被用到,也推荐使用
*/
public class Singlenton2 {
   //构造函数私有化
   private Singlenton2(){}
   //静态变量
   private static Singlenton2 instance;
   //静态代码块
   static {
       instance = new Singlenton2();
   }
   //静态公共方法
   public static Singlenton2 getInstance(){
       return  instance;
   }
}

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

/*
实例用的时候才创建,只能在单线程下使用
实际开发中不使用
*/
public class Singlenton3 {
    //构造函数私有化
    private Singlenton3() {
    }

    //静态变量
    private static Singlenton3 instance;

    //静态公共方法
    public static Singlenton3 getInstance() {
        if (instance == null) {
            instance = new Singlenton3();
        }
        return instance;
    }
}

4.懒汉式(线程安全,同步方法)

/*
加入了同步处理代码
每次执行getInstance()方法都要进行同步,效率低,不推荐使用
*/
public class Singlenton4 {
    //构造函数私有化
    private Singlenton4() {
    }

    //静态变量
    private static Singlenton4 instance;

    //静态公共方法
    public static synchronized Singlenton4 getInstance() {
        if (instance == null) {
            instance = new Singlenton4();
        }
        return instance;
    }
}

5.懒汉式(线程不安全,同步代码块)

/*
线程不安全,会产生多个实例
*/
public class Singlenton4 {
    //构造函数私有化
    private Singlenton4() {
    }

    //静态变量
    private static Singlenton4 instance;

    //静态公共方法
    public static  Singlenton4 getInstance() {
        if (instance == null) {
            synchronized (Singlenton4.class){
                instance = new Singlenton4();
            }
        }
        return instance;
    }

6.双重检查

/*
推荐使用
volatile:轻量级同步锁
*/
public class Singlenton6 {
    //构造函数私有化
    private Singlenton6() {
    }

    //静态变量
    private static volatile Singlenton6 instance;

    //静态公共方法
    public static Singlenton6 getInstance() {
        if (instance == null) {
            synchronized (Singlenton6.class) {
                if (instance == null) {
                    instance = new Singlenton6();
                }
            }
        }
        return instance;
    }
}

7.静态内部类

/*
采用了类装载的机制来保证初始化实例只有一个进程

静态内部类特点:
1.外部类被装载时,静态内部类不会被装载
2.调用静态内部类时才被装载(JVM装载类时线程安全的),而且只会加载一次

特点:私有静态内部类里有一个静态属性

推荐使用
*/
public class Singlenton7 {
    //构造函数私有化
    private Singlenton7() {
    }
	//静态内部类里有一个静态属性
    private static class SingletonInstance{
        public static final Singlenton7 INSTANCE = new Singlenton7();
    }

    //静态公共方法
    public static Singlenton7 getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

8.枚举

/*
不仅能避免多线程同步问题,还能防止反序列化重写创建新的对象
推荐使用
*/
public enum  Singlenton8 {
    INSTANCE;
    public void test(){
        System.out.println("test");
    }
}

JDK内单例模式:java.lang.Runtime (饿汉模式)

public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    /**
     * Returns the runtime object associated with the current Java application.
     * Most of the methods of class <code>Runtime</code> are instance
     * methods and must be invoked with respect to the current runtime object.
     *
     * @return  the <code>Runtime</code> object associated with the current
     *          Java application.
     */
    public static Runtime getRuntime() {
        return currentRuntime;
    }

    /** Don't let anyone else instantiate this class */
    private Runtime() {}
posted @ 2022-05-13 15:57  pizisu  阅读(22)  评论(0编辑  收藏  举报