解决的问题:可以保证一个类在内存中的对象唯一性
对象唯一性
1.不允许其他程序用new创建对象。
2.在该类创建一个本类实例。
3.对外提供一个方法让其他程序可以获得该对象。
步骤:
1.私有化该类构造函数。
2.通过new在本类中创建一个本类对象。
3.定义一个共有的方法,将创建的对象返回。
饿汉式:(饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。)
public class Singleton {
// 在类初始化时,已经自行实例化
private Singleton() {
};
private static final Singleton single = new Singleton();
public static Singleton getInstance() {
return single;
}
}
懒汉式:(线程不安全)
public class Singleton {
// 在第一次调用的时候实例化自己
private Singleton() {
};
private static Singleton single = null;
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
懒汉式(在getinstance上加上synchroized)public class Singleton {
// 在第一次调用的时候实例化自己
private Singleton() {
};
private static Singleton single = null;
public static synchronized Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
懒汉式(双重锁定)
public class Singleton {
// 在第一次调用的时候实例化自己
private Singleton() {
};
private static Singleton single = null;
public static Singleton getInstance() {
if (single == null) {
synchronized (Singleton.class) {
if (single == null) {
single = new Singleton();
}
}
}
return single;
}
}
懒汉式(静态内部类)(推荐)
public class Singleton {
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton() {
}
public static final Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
主要区别:
线程安全:
饿汉式天生就是线程安全的。
懒汉式本身是非线程安全的。
资源加载和性能:
饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,
但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成,
而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要做初始化,
如果要做的工作比较多,性能上会有些延迟,之后就和饿汉式一样了。