单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

main函数测试

public class Main {

    public static void main(String[] args) {
    // write your code here
     singleton5 instance = singleton5.getInstance();
     singleton5 instance1 = singleton5.getInstance();
     System.out.println(instance.hashCode());
     System.out.println(instance1.hashCode());

    }
}

饿汉式

//饿汉式
class singleton{
    //构造器私有化,外部不能new
    private singleton(){

    }
    //本类内部创建实例对象
    private final static singleton instance = new singleton();
    //提供一个公有的静态方法,返回实例对象
    public static singleton getInstance(){
        return instance;
    }
}

警惕代码块(饿汉式)

//警惕代码块(饿汉式)
public class singleton2 {
    //构造器私有化,外部不能new
    private singleton2(){

    }
    //本类内部创建实例对象
    private  static singleton2 instance;
    static {//静态代码中创建单例对象
        instance = new singleton2();
    }
    //提供一个公有的静态方法,返回实例对象
    public static singleton2 getInstance(){
        System.out.println("2");
        return instance;
    }
懒汉式(线程不安全)实际开发不使用
//懒汉式(线程不安全)实际开发不使用
public class singleton3 {
    public static singleton3 instance;

    private singleton3(){}
    //提供一个静态的公有方法,当使用到该方法时才会去创建instance
    public static singleton3 getInstance(){
        if (instance == null){//在多线程的情况下如果一个线程通过if判断且尚未new成功,
                              // 而另一线程也已进入,则会产生多个实例,造成线程不安全
            instance = new singleton3();
            System.out.println("3");
        }
        return instance;
    }
懒汉式同步方法(不推荐,效率太低)
//懒汉式同步方法(不推荐,效率太低)
public class singleton4 {
    public static volatile singleton4 instance;

    private singleton4(){}
    //提供一个静态的公有方法,加入同步进程代码,结局线程安全问题

    public static synchronized singleton4 getInstance(){
        if (instance == null) {
            {
                instance = new singleton4();
                System.out.println("4");
            }
        }
        return instance;
    }
推荐方法
//推荐
public class singleton5 {
    public static singleton5 singleton5;

    private singleton5() {
    }
    //提供一个静态的公有方法,加入同步进程代码,结局线程安全问题,同时结局加载问题
    //保证了效率
    public static singleton5 getInstance() {
        if (singleton5 == null) {
            synchronized (singleton5.class) {
                if (singleton5 == null) {
                    singleton5 = new singleton5();

                }
            }

        }
        System.out.println("5");
        return singleton5;
    }
使用枚举可以实现单例(推荐)
public class enumerate {
    public static void main(String[] args) {
        Singleton instance = Singleton.INSTANCE;
        Singleton instance1 = Singleton.INSTANCE;
        System.out.println(instance == instance1);
        System.out.println(instance.hashCode());
        System.out.println(instance1.hashCode());
        instance.sayOK();
    }
}
//使用枚举可以实现单例(推荐)
enum Singleton{
    INSTANCE;//属性
    public void sayOK(){
    System.out.println("OK");
    }
}

优点:

  • 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
  • 2、避免对资源的多重占用(比如写文件操作)。

缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

posted @ 2020-04-26 10:47  blank000  阅读(122)  评论(0)    收藏  举报