设计模式 单例模式

单例模式 ——保证一个类仅有一个实例,并提供一个访问它的全局访问点。

单例模式(Singleton)的目的是为了保证在一个进程中,某个类有且仅有一个实例。

单例模式的实现方式很简单:

  1. 只有private构造方法,确保外部无法实例化;
  2. 通过private static变量持有唯一实例,保证全局唯一性;
  3. 通过public static方法返回此唯一实例,使外部调用方能获取到实例。
package com.learn.singleton;

public class Earth {

    //静态字段引用唯一实例
    private static final Earth instance=new Earth();

    private String name="earth";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    //private 构造方法保证外部无法实例化
    private Earth(){

    }

    //通过静态方法返回实例
    public static Earth getInstance(){
        return instance;
    }
}

Java标准库有一些类就是单例,例如Runtime这个类:

Runtime runtime = Runtime.getRuntime();

延迟加载,即在调用方第一次调用getInstance()时才初始化全局唯一实例,类似这样:

public class Singleton {
    private static Singleton INSTANCE = null;

    public static Singleton getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }

    private Singleton() {
    }
}

遗憾的是,这种写法在多线程中是错误的,在竞争条件下会创建出多个实例。必须对整个方法进行加锁:

public synchronized static Singleton getInstance() {
    if (INSTANCE == null) {
        INSTANCE = new Singleton();
    }
    return INSTANCE;
}

但是加锁会严重影响性能。

另一种实现Singleton的方式是利用Java的enum,因为Java保证枚举类的每个枚举都是单例,所以我们只需要编写一个只有一个枚举的类即可:

package com.learn.singleton;

public enum World {

    INSTANCE;

    private String name="world";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package com.learn.singleton;

public class Test {

    public static void main(String[] args) {
        Earth earth=Earth.getInstance();
        System.out.println(earth.getName());

        World world=World.INSTANCE;
        System.out.println(world.getName());
    }
}

测试结果如下

实际上,很多程序,尤其是Web程序,大部分服务类都应该被视作Singleton,如果全部按Singleton的写法写,会非常麻烦,所以,通常是通过约定让框架(例如Spring)来实例化这些类,保证只有一个实例,调用方自觉通过框架获取实例而不是new操作符:

@Component // 表示一个单例组件
public class MyService {
    ...
}

因此,除非确有必要,否则Singleton模式一般以“约定”为主,不会刻意实现它。

 

单例模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值