设计模式-单例模式
单例模式的意图
某个类在程序运行过程中只被实例化一次,也就是说该类在程序的生存周期里只有一个实例对象。
特点
- 单例类只能有一个实例。
- 单例类必须自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例。
好处
由于这个类只实例化一次,不管多少个类中用到了这个类,也都只有一个该类的对象。因此,减少了类实例对象的创建 --> 减小了GC压力 --> 提升了程序的性能。
实现思路
使用一个私有构造函数、一个私有静态变量以及一个公有静态函数来实现。私有构造函数保证了不能通过构造函数来创建对象实例,只能通过公有静态函数返回唯一的私有静态变量。
::: hljs-center
:::
代码实现
懒汉式-线程不安全
以下实现中,私有静态变量 uniqueInstance 被延迟实例化,这样做的好处是,如果没有用到该类,那么就不会实例化 uniqueInstance,从而节约资源。
这个实现在多线程环境下是不安全的,如果多个线程能够同时进入 if (uniqueInstance == null)
,并且此时 uniqueInstance 为 null,那么会有多个线程执行 uniqueInstance = new Singleton();
语句,这将导致实例化多次 uniqueInstance。
实现
/**
* 懒汉式-线程不安全
* 私有静态变量 uniqueInstance 被延迟实例化,这样做的好处是,如果没有用到该类,那么就不会实例化 uniqueInstance,从而节约资源。
*
* 这个实现在多线程环境下是不安全的,
* 如果多个线程能够同时进入 if (uniqueInstance == null) ,
* 并且此时 uniqueInstance 为 null,
* 那么会有多个线程执行 uniqueInstance = new Singleton(); 语句,
* 这将导致实例化多次 uniqueInstance。
*
* @author zhongyufeng
* @date 2021-10-27 15:17
*/
public class LazySingleton {
//将自身类型作为静态属性
private static LazySingleton uniqueInstance;
//私有化构造器,使其无法被外部实例化,保证对象只能在内部创建
private LazySingleton() {
//这里测试多线程情况下是否会创建多个对象,这里可以看到,在多个线程进入的情况下,该对象会被创建多次
System.out.println("对象被创建了。。。");
}
/**
* 外部只能通过这个类的静态方法获取这个类的实例对象
* 并且在这个方法中,只会在第一次被调用时,创建一个实例对象,
* 后续再被调用时,直接使用之前创建过的对象,即为懒汉单例模式
* @param
* @return com.zyf.singleton.LazySingleton
* @author zhongyufeng
* @date 2021/10/27 15:20
*/
public static LazySingleton getUniqueInstance() throws InterruptedException {
//第一次被调用时,对象未被创建,所以在此创建一次对象
if (uniqueInstance == null) {
//故意在此处阻塞1秒,模拟多个线程进入的情况
Thread.sleep(1000);
uniqueInstance = new LazySingleton();
}
//后续调用时,对象不为nll,直接返回同一个对象
return uniqueInstance;
}
}
测试
public static void main(String[] args) {
//线程任务
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
LazySingleton uniqueInstance = LazySingleton.getUniqueInstance();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//启用100个线程
for (int i = 0; i < 100; i++) {
Thread thread = new Thread(runnable);
thread.start();
}
}
上面测试代码运行结果可以看到输出了很多次 对象被创建了。。。
,证明这种实现方式确实不是安全的。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 奇怪的阿峰
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果