前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式入门:单例模式

设计模式入门:单例模式

作者头像
佛系贲八拉
修改2021-09-10 18:01:35
1790
修改2021-09-10 18:01:35
举报
文章被收录于专栏:学技术学技术

### UML类图

![单例模式](http://upload-images.jianshu.io/upload_images/9709135-eba21220b6f018cd.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

### 代码示例

1. 饿汉式

``` java

/**

* 单例模式:饿汉式

* <p>

* a.线程安全

* b.提前初始化(占用资源)

* c.类加载慢但获取对象快

*/

public class HungrySingleton {

private static final HungrySingleton INSTANCE = new HungrySingleton();

/**

* 私有构造器

*/

private HungrySingleton() {

}

/**

* 获取当前实例的唯一入口

*

* @return 当前实例

*/

public static HungrySingleton getInstance() {

return INSTANCE;

}

}

```

2.1 懒汉式

``` java

/**

* 单例模式:懒汉式

* <p>

* a.非线程安全

* b.实现延迟加载

* c.类加载快但获取对象慢

*/

public class LazySingleton {

private static LazySingleton instance = null;

/**

* 私有构造器

*/

private LazySingleton() {

}

/**

* 获取当前实例的唯一入口

* 多线程下非线程安全

*

* @return 当前实例

*/

public static LazySingleton getInstance() {

if (instance == null) {

instance = new LazySingleton();

}

return instance;

}

}

```

2.2 懒汉式(同步锁synchronized)

``` java

/**

* 单例模式:懒汉式(synchronized)

* <p>

* a.非线程安全

* b.实现延迟加载

* c.类加载快但获取对象慢

*/

public class SynchronizedSingleton {

private static SynchronizedSingleton instance = null;

/**

* 私有构造器

*/

private SynchronizedSingleton() {

}

/**

* 获取当前实例的唯一入口

* 通过synchronized机制保证多线程安全,但同时也消耗较多的性能

*

* @return 当前实例

*/

public static synchronized SynchronizedSingleton getInstance() {

if (instance == null) {

instance = new SynchronizedSingleton();

}

return instance;

}

}

```

2.3 懒汉式(DCL)

``` java

/**

* 单例模式:懒汉式(双重检测锁。DCL , Double-checked Locking)

* <p>

* a.非线程安全

* b.实现延迟加载

* c.类加载快但获取对象慢

*/

public class DCLSingleton {

/**

* volatile确保了实例的可视性

*/

private static volatile DCLSingleton instance = null;

/**

* 私有构造器

*/

private DCLSingleton() {

}

/**

* 获取当前实例的唯一入口

* 通过DCL机制保证多线程安全,同时消耗较少的性能

*

* @return 当前实例

*/

public static DCLSingleton getInstance() {

if (instance == null) {

synchronized (DCLSingleton.class) {

if (instance == null) {

instance = new DCLSingleton();

}

}

}

return instance;

}

}

```

3. 静态内部类

``` java

/**

* 单例模式:登记式(静态内部类)

* <p>

* a.线程安全

* b.实现延迟加载

*/

public class InnerClassSingleton {

/**

* 静态内部类,用于初始化调用时实例化当前 instance

*/

private static class InnerStaticClassHolder {

private static final InnerClassSingleton INSTANCE = new InnerClassSingleton();

}

/**

* 私有构造器

*/

private InnerClassSingleton() {

}

/**

* 获取当前实例的唯一入口

* 通过对静态域使用延迟初始化达到延迟加载的效果

* (只有通过显式调用 getInstance 方法时,才会显式装载 InnerStaticClassHolder 类,从而实例化 instance)

*

* @return 当前实例

*/

private static InnerClassSingleton getInstance() {

return InnerStaticClassHolder.INSTANCE;

}

}

```

4. 枚举

``` java

/**

* 单例模式:枚举

* <p>

* a.线程安全

* b.非延迟加载

* c.代码更简洁,支持序列化机制

* ps: 这是实现单例模式的最佳方式,但未被广泛使用。

*/

public enum EnumSingleton {

/**

* 该定义用于返回当前实例

*/

INSTANCE;

}

```

### 总结思考

&emsp;&emsp;单例模式属于创建型模式,是一种较为简单的设计模式,但也是最容易让人犯错的。在不同的单例模式实现中,首先要确保构造函数是私有的,然后提供一个静态入口(方法)用于获取唯一的实例。

&emsp;&emsp;大多数情况下,不建议使用非线程安全的以及synchronized监视器锁实现的懒汉方式,在资源允许的情况下尽可能使用饿汉模式。如果明确要实现 lazy loading 效果时,可以使用静态内部类形式。如果涉及到反序列化创建对象时,可以尝试使用枚举方式。如果有其他特殊的需求,可以考虑使用DCL双检锁的方式。

> [示例代码](https://github.com/happyjared/java-learning/tree/master/design-patterns)

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
日志服务
日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集、日志存储到日志检索,图表分析、监控告警、日志投递等多项服务,协助用户通过日志来解决业务运维、服务监控、日志审计等场景问题。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档