使用场景
• 程序运行只需要一个类的实例
• 需要频繁创建和销毁的对象
• 创建对象时消耗时间过多,但又经常用到的对象
单例的必要条件
• 构造器私有化
• 实例必须是一个且唯一,并且必须加上static属性
• 统一由一个静态方法供外界获取单例
两种实现模式
懒汉单例
可理解为懒加载模式,在使用的时候才会实例化。
但是会有问题,如果多线程访问,会线程不安全
public class Test {
private Test() {
}
private static Test instance;
public static Test getInstance() {
if (instance == null) {
instance = new Test();
}
return instance;
}
}
所以多线程使用懒汉模式的时候要考虑线程安全
public static void main(String[] args) {
Thread thread = new Thread() {
@Override
public void run() {
Test instance = Test.getInstance();
System.out.println(instance);
}
};
thread.start();
Test instance = Test.getInstance();
System.out.println(instance);
}
lesson3.Test@a09ee92
lesson3.Test@7d77bb0a
可以看到输出的类并非单例,而是存在多个实例
所以如果懒汉要有多线程访问要用线程锁
public class Test {
private Test() {
}
private Integer age;
private static Test instance;
public static Test getInstance() {
if (instance == null) {
synchronized (Test.class) {
if (instance == null) {
instance = new Test();
}
}
instance = new Test();
}
return instance;
}
}
饿汉单例
public class Test {
private Test() {
}
private static final Test INSTANCE = new Test();
public static Test getInstance() {
return INSTANCE;
}
}