8种单例模式
不会设计模式,何以叫java工程师?
若有不恰之处,请各位道友指正~
饿汉式(静态常量)
-
优点:在类加载的时候就完成了实例化,避免了多线程同步问题
-
缺点:在类加载的时候就完成实例化,没有达到懒加载,如果没有用到就会造成内存浪费
-
因为类加载的原因不仅仅是调用getInstance 方法的调用,还有很多其他因素,达不到懒加载(lazy loading)的效果
// 推荐 ,一般用于程序中保证会实例化的对象,工具类等
class Singleton1{
private static final Singleton1 instance = new Singleton1();
private Singleton1(){
}
public static Singleton1 getInstance(){
return instance;
}
}
饿汉式(静态代码块)
- 饿汉式(静态常量) 效果一样
比较直接喜欢先上代码看,容易理解:
class Singleton2{
private static final Singleton2 instance;
static {
instance = new Singleton2();
}
private Singleton2(){
}
public static Singleton2 getInstance(){
return instance;
}
}
懒汉式(非线程安全)
- 非线程安全,不推荐
class Singleton3{
private static Singleton3 instance;
private Singleton3(){
}
public static Singleton3 getInstance(){
if(instance == null){
instance = new Singleton3();
}
return instance;
}
}
懒汉式(线程安全)
class Singleton4{
private static Singleton4 instance;
private Singleton4(){
}
public static synchronized Singleton4 getInstance(){
if(instance == null){
instance = new Singleton4();
}
return instance;
}
}
懒汉式(同步代码块)
- (线程安全,同步代码块) 实际多线程也会出现线程问题
class Singleton5{
private static Singleton5 instance;
private Singleton5(){
}
public static Singleton5 getInstance(){
if(instance == null){
synchronized (Singleton5.class){
instance = new Singleton5();
}
}
return instance;
}
}
双重检查(double-check)
- 优点:double-check 保证了线程安全
- 使用 if(instance == null) 避免反复进行方法同步
- 线程安全,延迟加载
//推荐
class Singleton6{
private static volatile Singleton6 instance;
private Singleton6(){
}
public static Singleton6 getInstance(){
if(instance == null){
synchronized (Singleton5.class){
if(instance == null){
instance = new Singleton6();
}
}
}
return instance;
}
}
静态内部类
- 静态内部类方式在 Singleton 类加载时,并不会立即实例化,而是在需求时调用 getInstance 时 ,
- 才会装载SingletonInstance,从而完成 Singleton 实例化。
//推荐
class Singleton7{
private Singleton7(){
}
private static class SingletonInstance{
private static final Singleton7 INSTANCE = new Singleton7();
}
public static Singleton7 getInstance(){
return SingletonInstance.INSTANCE;
}
}
枚举
- 用枚举不仅可以避免多线程同步问题,还能防止反序列化重新创建对象
- Effective Java 作者推荐的
/**
* @Author: shengjm
* @Date: 2020/2/13 13:22
* @Description: 枚举实现单例模式
*/
public class SingleClass{
private enum Singleton{
INSTANCE;
private final SingleClass instance;
Singleton(){
instance = new SingleClass();
}
public SingleClass getInstance(){
return instance;
}
}
public static SingleClass getInstance(){
return Singleton.INSTANCE.getInstance();
}
}