设计模式-创建型模式-单例

本文详细介绍了单例模式的四种实现方式:饿汉式、懒汉式、双重同步锁及使用静态内部类。并探讨了每种方式的特点及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单例模式保证一个类只有一个对象,并且提供一个访问该实例的全局访问点。

tips:20181118更新
《Head First 设计模式》中关于单例中说明单例不会被jvm回收。被回收的版本是jdk1.2或更早版本。
《Head First 设计模式》中关于单例中说明双重同步锁可以使用不会有问题,问题版本是jdk1.4或更早版本。

1.单例模式实例一(饿汉式)

public class Singleton {
	private static Singleton sin = new Singleton(); /// 直接初始化一个实例对象
	private Singleton() { /// private类型的构造函数,保证其他类对象不能直接new一该对象的实例
	}
	public static Singleton getSin() { /// 该类唯一的一个public方法
		return sin;
	}
}

上述代码中的一个缺点是该类加载的时候就会直接new 一个静态对象出来,当系统中这样的类较多时,会使得启动速度变慢。现在流行的设计都是讲延迟加载,我们可以在第一次使用的时候才初始化第一个该类对象。 

2单例模式实例二(懒汉式)

public class Singleton {
	private static Singleton instance;
	private Singleton() {
	}
	public static synchronized Singleton getInstance() { // 对获取实例的方法进行同步
		if (instance == null)
			instance = new Singleton();
		return instance;
	}
}

3单例模式实例三(双重同步锁),

public class Singleton {  
    private static Singleton instance;  
    private Singleton (){
    }   
    public static Singleton getInstance(){    //对获取实例的方法进行同步
      if (instance == null){
         synchronized(Singleton.class){
             if (instance == null)
                 instance = new Singleton(); 
     }
     }
     return instance;
   }
}

这里面的疑问可能是为什么要做两次判断和锁定Singleton.class
问题一:两个线程同时访问,当线程A的线程B同时访问,都获得instancenull,只有一个线程可以锁定Singleton.class,假设A执行完毕,获得对象,B被唤醒在进行访问时不判断一次,那么就new 出了一个新对象。
问题二:因为是静态方法,所以它只有class可以锁定,没有this锁定。

4.单例模式实例四(使用静态内部类)

public class Singleton {
	private Singleton() {
	}
	public static Singleton getInstance() {
		return Inner.s;
	}
	private static class Inner{
		static Singleton s = new Singleton();
	}
}

你可能认为这与第一种相同,焦点在于是不是延迟加载,静态内部类对于外部成员只有在第一次调用时才被加载。

破解单例模式(不能破解枚举单例)

单例模式可以通过反射或反序列化进行破解
举例代码如下

Class clazz = (Class) Class.forName("com.singleton.Singleton");
Constructor<Singleton> con = clazz.getDeclaredConstructor(null);
con.setAccessible(true);//跳过权限检查
Singleton s = con.newInstance(null);
System.out.println(s);



 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值