Java单例模式

在23中设计模式中,单利模式使我们最先接触的,也是我们经常使用的一种设计模式。

设计模式就是指在整个程序运行中,有且只有一个实例存在。

1.简易实现

设计单利模式,我们会首先将构造方法私有化,保证外部无法调用构造方法创建对象。然后对外抛出一个静态方法获取实例。

public class Singleton {
    private static Singleton singleton = new Singleton();

    private Singleton() {
    }

    private static Singleton getInstance() {
        return singleton;
    }
}
2.延迟加载

虽然我们实现了单例模式,可是却存在一个问题,因为静态实例不管你是否调用 getInstance() 方法都会创建。如果程序中这样的单例很多,并且还没有被调用,将会无端的浪费很多资源。

public class Singleton {
    private static Singleton singleton = null;

    private Singleton() {
    }

    private static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}
方法同步

先不初始化静态实例,在调用 getInstance() 方法中,先判断实例是否为空,然后再创建实例,这样就解决了无端浪费资源的问题。

这样的实现方式在单线程中运行没有问题,如果放在多线程的运行条件下,就会有一些隐藏的问题出现。我们在创建实例的时候,如果实例还没有创建,其他线程也在运行,当它判断实例是否为空时,此时实例还没有创建,他就会重复创建实例,导致一些隐藏的问题。

public class Singleton {
    private static Singleton singleton = null;

    private Singleton() {
    }

    private synchronized static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}
代码块同步

虽然解决了多线程问题,但是在方法这里写代码片加上 synchronized 关键字将比原始方法在效率上低好多。

public class Singleton {
    private static Singleton singleton = null;

    private Singleton() {
    }

    private static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
volatile关键字

代码块同步就比方法同步在效率上高很多。多线程有许多的未知性,除了重复创建实例这种情况,还有另外一种情况也有可能发生,尽管概率很小。
创建实例的需要两个步骤来执行。1.分配内存,将引用指向分配的内存地址。2.在内存中进行初始化操作。这两个步骤的顺序并没有明确定义,所以有一种可能,是先分配了内存地址将引用指向该地址,还没有进行初始化操作。此时若有线程判断实例是否为空,因为引用已经指向了内存地址,所以不为空,此时操作实例也会有一些隐藏的问题。

public class Singleton {
    private volatile static Singleton singleton = null;

    private Singleton() {
    }

    private static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值