单例模式是设计模式里面最为简单和基础的一个模式,以前初学Java的时候已经了解到这个模式,但也只是仅仅明白了一两种,随着工作后代码量的增加,随之而来对Java有所熟练,重新看了相关的资料,更加明白了其他的一些单例模式实现方法,所以说,设计模式是适合有一定代码量的程序猿去学习的,学习的过程中会有一些似曾相识的感觉。
总体来说,我目前学到的单例模式的实现方式共有五种,分别是懒汉式、饿汉式、双重检测锁、静态内部类和枚举类方式。
最为简单的是懒汉式和饿汉式,他们也是双重检测锁和静态内部类这两种实现形式的基础。
首先要说的是懒汉式,顾名思义,懒汉式就是类的实例不会再类加载的时候创建,即会延迟创建,这样带来的影响即需要在后期创建实例,因为需要考虑到线程安全,所以需要加上锁,因此会导致效率问题,下面贴上相应的代码:
public class SingletonLazy {
private static SingletonLazy instance;
private SingletonLazy() {
}
public synchronized static SingletonLazy getInstance() {
if (instance == null) {
instance = new SingletonLazy();
}
return instance;
}
}
相反,饿汉式则会在类加载时创建实例,因此避免了加锁导致的效率问题,但由此可能带来提早创建实例但不会被时候的资源浪费问题,相关代码如下:
public class SingletonStarve {
private static SingletonStarve instance = new SingletonStarve();
private SingletonStarve() {
}
public static SingletonStarve getInstance() {
return instance;
}
}
基于以上两种实现方式,后面有了双重检测锁模式和静态内部类。当然,在学习的过程中了解到,双重检测锁的实现方式可能会因为JVM的问题而导出出现差错,所以不推荐使用,相应的代码如下:
public class SingletonDoubleLock {
private static SingletonDoubleLock instance = null;
public static SingletonDoubleLock getInstance() {
if (instance == null) {
SingletonDoubleLock dl = null;
synchronized (SingletonDoubleLock.class) {
dl = instance;
if (dl == null) {
synchronized (SingletonDoubleLock.class) {
if (dl == null) {
dl = new SingletonDoubleLock();
}
}
instance = dl;
}
}
instance = dl;
}
return instance;
}
private SingletonDoubleLock() {
}
}
静态内部内是一个比较好的实现方式, 因为加载SingletonStaticClass的时候不会立即加载静态内部类,所以是懒加载。
public class SingletonStaticClass {
private static class getInstanceClass {
private static SingletonStaticClass instance = new SingletonStaticClass();
}
private SingletonStaticClass() {
}
public static SingletonStaticClass getInstance() {
return getInstanceClass.instance;
}
}
枚举类实现方式比较简单,但没有懒加载,代码如下:
public enum SingletonEnum {
//这个枚举元素本身就是单例
INSTANCE;
public void singletonOperation(){
}
}
注:学习自尚学堂-高淇老师的相关视频