单例模式就是在堆中只存在一份实例,这样的好处就是可以节省内存,但是也可可能引发多线程问题,所以在单例中最好把不要设置可供外界访问的成员变量。
Java中实现单例模式一共有七种,首先都需要将静态方法私有化,具体如下
将构造方法私有化后使用静态常量进行初始化,对外提供一个静态方法返回。
public class Singleton {
private Singleton() {
}
private static final Singleton SINGLETON = new Singleton();
public static Singleton getSingleton() {
return SINGLETON;
}
}
根据静态代码块在类初始化时只会加载一次,而且JVM保证了类加载时是线程安全的。所以此方式效率也很高,但是有个缺陷就是无论使用与否都会在内存中存在一份实例,若不使用到的时候会造成内存浪费一点
public class Singleton2 {
private Singleton2() {
}
private static Singleton2 SINGLETON2;
static {
/**
* 静态代码块会在类加载时执行 在构造函数之前
*/
SINGLETON2 = new Singleton2();
}
public static Singleton2 getSingleton2() {
return SINGLETON2;
}
}
此方式线程不安全,因为在创建实例时,当多个线程都成功进入到创建实例过程中后,就会创建多个对象。
public class Singleton3 {
private Singleton3() {
}
private static Singleton3 instance = null;
public static Singleton3 getInstance() {
if (instance == null) {
instance = new Singleton3();
}
return instance;
}
}
根据3改正,因为可能存在多个线程同时进入,所以直接加个synchronized来保证线程安全,但是锁的粒度较大,当有很多线程过来时即使已经创建过实例也要进行同步,等待去获得锁对象
public class Singleton4 {
private Singleton4() {
}
private static Singleton4 instance = null;
public static synchronized Singleton4 getInstance() {
if (instance == null) {
instance = new Singleton4();
}
return instance;
}
}
根据4改编,既然锁方法的粒度太大那么就锁销粒度,使用同步代码块的方式进行,如果对象没有创建就使用同步代码块去创建,Spring中的实现也是类似。这样的当对象实例创建完成后则不会进入同步代码块
public class Singleton5 {
private Singleton5() {
}
private static Singleton5 instance = null;
public static synchronized Singleton5 getInstance() {
if (instance == null) {
synchronized (Singleton5.class) {
if (instance == null) {
instance = new Singleton5();
}
}
}
return instance;
}
}
根据静态加载时才会被初始化的特性,再根据类加载时是线程安全的
public class Singleton6 {
private Singleton6() {
}
private static class Instance {
/**
* 静态内部类只有在使用时会被初始化一次
*
*/
private static final Singleton6 instance = new Singleton6();
}
public static Singleton6 getInstance() {
//调用静态内部类的静态常量
return Instance.instance;
}
}
枚举类型天然单例 是实现单例模式的最佳实践,因为序列化反序列化后也是单例模式
enum Singleton8 {
/**
* 实例对象
*/
INSTANCE;
public void sayok() {
System.out.println("ok");
}
}
原文:https://www.cnblogs.com/clion/p/14143978.html