单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
解决的问题:一个全局使用的类,频繁的创建和销毁。
1. 饿汉式单例(立即加载)
// 饿汉式单例
public class Singleton1 {
// 私有构造
private Singleton1() {}
private static Singleton1 single = new Singleton1();
// 静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}
2. 懒汉式单例(延时加载)
// 懒汉式单例
public class Singleton2 {
// 私有构造
private Singleton2() {}
private static Singleton2 single = null;
public static Singleton2 getInstance() {
if(single == null){
single = new Singleton2();
}
return single;
}
}
饿汉式和懒汉式的区别:
饿汉式是一加载就把单例实例化,而懒汉式是当调用静态方法getInstance的时候,初始化单例。
饿汉式是线程安全的,懒汉线程不安全。
懒汉式改进:
方法加锁或者同步代码块加锁,保证了线程安全,但效率低。每次都要加锁解锁。代码入下
public class Singleton3 {
// 私有构造
private Singleton3() {}
private static Singleton3 single = null;
public static Singleton3 getInstance() {
// 等同于 synchronized public static Singleton3 getInstance()
synchronized(Singleton3.class){
// 注意:里面的判断是一定要加的,否则出现线程安全问题
if(single == null){
single = new Singleton3();
}
}
return single;
}
}
继续改进:
双重锁定方法。 先进行判断,若未被创建时,加锁。代码入下
public class Singleton4 {
// 私有构造
private Singleton4() {}
private static Singleton4 single = null;
// 双重检查
public static Singleton4 getInstance() {
if (single == null) {
synchronized (Singleton4.class) {
if (single == null) {
single = new Singleton4();
}
}
}
return single;
}
}
当然 ,还可以使用静态内部类,静态代码块,内部枚举类等方式