单例设计模式
单例设计模式是Java中最简单的设计模式之一,这种类型属于创建型模式,它提供了创建对象的最佳方式。
单例模式实现的实现
单例设计模式分类为两种:
饿汉式:类加载就会导致该单实例对象被创建
懒汉式:类加载不会导致该单实例对象被创建,首次使用才会创建。
饿汉式-方式1(静态变量):
public class Singleton1 {
private Singleton1(){
}
private static Singleton1 instance = new Singleton1();
public static Singleton1 getInstance(){
return instance;
}
}
饿汉式-方式2(静态代码块):
public class Singleton2 {
private Singleton2(){};
private static Singleton2 singleton2;
static {
singleton2 = new Singleton2();
}
public static Singleton2 getinstance(){
return singleton2;
}
}
上面这两种方式创建单例对象的方式基本一样,因为类加载是线程安全的,故这两种都是线程安全的创建方式,但有可能对象创建出来但是不使用,因此存在浪费内存的情况。
懒汉式-方式1(双重检查):
public class Singleton3 {
private Singleton3(){};
private static volatile Singleton3 instance;
public static Singleton3 getInstance(){
if(instance == null){
synchronized (Singleton3.class){
if(instance == null) {
instance = new Singleton3();
}
}
}
return instance;
}
}
这里
volatile
主要用来防止指令重排,这种方式是线程安全的
懒汉式-方式1(静态内部类):
public class Singleton4 {
private Singleton4(){
}
private static class SingletonHandle{
private static final Singleton4 instance = new Singleton4();
}
public Singleton4 getinstance(){
return SingletonHandle.instance;
}
}
这种方式属于懒汉式,因为静态内部类在外部访问内部变量时才会加载。
饿汉式-方式3(枚举):
枚举类是实现单例模式最推荐的一种方式,因为枚举类是线程安全的,并且只会装载一次,可以充分利用枚举类这个特性来实现单例模式,且不会被反射破环,实现起来简单
public enum Singleton5 {
SINGLETON_5;
}
学习了这几种方式,那我们看看JDK中有哪些类使用了单例设计模式吧。
Runtime类 - 这个类使用了单例模式,因为系统中的运行时对象只有一个。通过Runtime.getRuntime()方法可以获取到这个实例。
public class Runtime {
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
}
我们可以看到它是使用了静态变量这种方式实现的。