单例模式:
应用场合:一个类在内存中只存在一个对象,保证整个应用程序中某个实例有且只有一个。
类型:饿汉模式,懒汉模式
- 饿汉模式
/**
* 饿汉模式
*
*/
public class Singleton {
// 1.将构造函数私有化
private Singleton() {
}
// 2.创建唯一实例,并初始化
private static Singleton instance = new Singleton();
// 3.提供一个获取实例的接口
public static Singleton getInstance() {
return instance;
}
}
- 懒汉模式(对象的延时加载)
/**
* 懒汉模式
*
*/
public class Singleton2 {
// 1.将构造函数私有化
private Singleton2() {
}
// 2.创建唯一实例,不初始化
private static Singleton2 instance;
// 3.提供获取实例的接口
public static Singleton2 getInstance() {
if (instance == null) // 判断是否为空
instance = new Singleton2();
return instance;
}
}
测试类
public class Test {
public static void main(String[] args) {
/**
* 饿汉模式
*/
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
if (s1 == s2) {
System.out.println("s1和s2是同一个实例");
} else {
System.out.println("s1和s2不是同一个实例");
}
/**
* 懒汉模式
*/
Singleton2 s21 = Singleton2.getInstance();
Singleton2 s22 = Singleton2.getInstance();
if (s21 == s22) {
System.out.println("s21和s22是同一个实例");
} else {
System.out.println("s21和s22不是同一个实例");
}
}
}
区别:
饿汉模式加载类时比较慢,运行时获取对象的速度比较快,线程安全的;
懒汉模式加载类时比较快,运行时获取对象的速度比价慢,线程不安全的。
解决懒汉模式线程不安全方法:
/**
* 懒汉模式 线程安全
*
*/
public class Singleton3 {
// 1.将构造函数私有化
private Singleton3() {
}
// 2.创建唯一实例,私有静态化
private static Singleton3 instance;
// 3.提供获取实例的接口
public static Singleton3 getInstance() {
//这样可以减少判断锁的次数
if (instance == null) {
synchronized (Singleton3.class) {
if (instance == null)
instance = new Singleton3();
}
}
return instance;
}
}
从Java1.5开始,还可以编写一个包含单个元素的枚举类型:
public enum Singleton3{
INSTANCE;
}