单例模式

单例模式是一个比较简单的模式,保证了这个类只有一个实例,而且自行实例化向整个系统提供这个实例

举个例子来说明单例的类只会产生一个实例

public class SingleTon {

    private int count;
    
    public void say() {
        System.out.println("hello world " + (count++));
    }
}


public class Client {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            SingleTon singleTon = new SingleTon();
            singleTon.say();
        }
    }
}

hello world 0
hello world 0
hello world 0
hello world 0
hello world 0

可以看到每一次我们都是new出来的一个新对象

那我们使用单例之后呢?

// 这只是单例的一种写法并且不是最好的,当前只是为了掩饰单例的作用
public class SingleTon {

    private static SingleTon singleTon = new SingleTon();

    private SingleTon() {
    }

    public static SingleTon getInstance() {
        return singleTon;
    }

    private int count;

    public void say() {
        System.out.println("hello world " + (count++));
    }
}


public class Client {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            SingleTon singleTon = SingleTon.getInstance();
            singleTon.say();
        }
    }
}

hello world 0
hello world 1
hello world 2
hello world 3
hello world 4

可以看到这是一个对象,这就是单例的作用

单例模式的优点

  • 由于单例模式在内存中只有一个实例,减少了内存开支
  • 由于单例模式只生成一个实例,所以减少了系统的性能开销
  • 单例模式可以避免对资源的多重占用,例如一个写文件动作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作
  • 单例模式可以在系统设置全局的访问点,优化和共享资源访问
  • spring的bean都是单例的

单例模式的缺点

  • 单例模式一般没有接口,扩展很困难
  • 单例模式对测试是不利的。在并行开发环境中,如果单例模式没有完成,是不能进行测试的
  • 单例模式与单一职责原则有冲突

比较推荐的三种单例写法

双重检查
public class Singleton {

    private static volatile Singleton singleton;

    private Singleton() {}

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

静态内部类

public class Singleton {

    private Singleton() {}

    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

枚举(JDK1.5之后)

public enum Singleton {
    INSTANCE;
    public void whateverMethod() {

    }
}

学习之余也不要忘了劳逸结合哦

喜欢天马行空的同学请关注公众号:

单例模式