单例(singleton):只允许创建一个该类的对象。
① 单例模式:饿汉式(线程安全、占资源)
- 天生线程安全(无锁)、类加载时创建(不用也会被创建,占用资源)
public class TestSingleton {
public static void main(String[] args) {
Singleton1 s1 = Singleton1.getInstance();
Singleton1 s11 = Singleton1.getInstance();
System.out.println(s1); // Singleton1@7852e922
System.out.println(s11); // Singleton1@7852e922
}
}
class Singleton1 {
// 私有静态常量引用,类加载执行就1份、不可调用、不可修改(始终单例)
private static final Singleton1 instance = new Singleton1();
// 私有构造,不可直接new对象
private Singleton1() {}
// 静态方法,类名直接调用,返回私有静态常量引用
public static Singleton1 getInstance() {
return instance;
}
}
② 单例模式:懒汉式(不安全、需要同步)
- 天生线程不安全(需同步锁、效率低)、使用时才创建
public class TestSingleton {
public static void main(String[] args) {
Singleton2 s2 = Singleton2.getInstance();
Singleton2 s22 = Singleton2.getInstance();
System.out.println(s2); // Singleton2@4e25154f
System.out.println(s22); // Singleton2@4e25154f
}
}
class Singleton2 {
// 私有静态引用,类加载执行就1份、不可调用
private static Singleton2 instance = null;
// 私有构造,不可直接new对象
private Singleton2() {}
// 同步锁、静态方法获取类的对象(引用为空则new,不为空则返回自身,始终单例)
public synchronized static Singleton2 getInstance() {
return instance == null ? instance = new Singleton2() : instance;
}
}
③ 单例模式:懒汉式(线程安全,静态内部类)
- 天生线程安全(无锁),使用时才创建(静态内部类)
public class TestSingleton {
public static void main(String[] args) {
Singleton3 s3 = Singleton3.getInstance();
Singleton3 s33 = Singleton3.getInstance();
System.out.println(s3); // Singleton3@70dea4e
System.out.println(s33); // Singleton3@70dea4e
}
}
class Singleton3 {
// 私有构造,不可直接new对象
private Singleton3() {}
// 静态内部类,不依赖外部类,使用时才需要创建,可独立创建
// 内部类中静态常量引用,一旦创建内部类,属性则不可修改(始终单例)
private static class Holder {
static final Singleton3 instancce = new Singleton3();
}
// 静态方法,获取内部类中创建的外部类对象的常量引用
public static Singleton3 getInstance() {
return Holder.instancce;
}
}