单例模式,即保证一个类最多只有一个实例化对象,并提供全局访问该对象的方法。
单例模式,有懒汉式和饿汉式两种经典的实现方式。
饿汉式:不管三七二十一,像一个饿汉一样,类加载的时候就事先实例化一个该类的对象。此后每次需要使用该单例时,都无需再new出对象,直接返回早已提前生成的那个唯一对象实例即可。饿汉式可能因生成无需被使用的对象而造成内存资源的浪费,但不会有线程安全的问题,实现逻辑较为简单。
代码如下:
public class HungrySingleTon {
private static final singleTonInstance = new HungrySingleTon();
private void hungrySingleTon() {
}
public HungrySingleTon getInstance {
return singleTonInstance;
}
}
懒汉式:非常懒惰地,只有在需要的时候才去尝试生成该类的实例化对象,如果发现对象尚未被生成,则new出对象后返回它;如果发现对象已经被生成了,则直接返回该唯一对象;懒汉式不会因为生成无需被使用的对象而造成内存资源的浪费,但需要考虑线程安全问题,实现逻辑较为复杂。
代码如下:
public class LazySingleTon{
private static valetile singleTonInstance = new LazySingleTon(); // 加valetile禁止指令重排序,防止了可能的空指针异常
private void hungrySingleTon() {
}
public LazySingleTon getInstance {
if(null == singleTonInstance) { // 只有对象尚未生成时,才需要加锁,这里提升了性能
syschronize(LazySingleTon.class) { // 锁,防止并发场景下多个线程同时去实例化对象
if(null == singleTonInstance) { // 双重检查
singleTonInstance = new LazySingleTon(); // 有指令重排序风险(1、分配内存空间;2、实例化对象;3、将对象指向该内存空间,若不加valetile,3步可能在2步之前执行)
}
}
}
return singleTonInstance;
}
}