什么是单例模式
单例(单个的实例)
创建一个唯一的对象
这个类只存在一个实例
单例模式有两种方式
1、饿汉式 2、懒汉式
1、饿汉式
没有使用这个实例也会创建实例,比如调用实例的静态属性也会创建实例
对象,通常是重量级的对象, 饿汉式可能造成创建了对象,但是没有使用
如何保障我们只能创建一个 GirlFriend 对象
步骤[单例模式-饿汉式]
- 将构造器私有化
- 在类的内部直接创建对象(该对象是 static)
- 提供一个公共的 static 方法,返回对象
public class ch {
public static void main(String[] args) {
Car car = Car.getInstance();
System.out.println(car.name);
}
}
class Car{
private String name;
//在类加载时创建Car对象,只执行一次
//为了在静态方法中访问需要定义为static
private static Car car = new Car("lldwb");
private Car(String name){
System.out.println("创建一个Car类");
this.name = name;
}
//提供一个公共的静态方法,返回Car对象
public static Car getInstance(){
return car;
}
}
2、懒汉式
调用对象时创建这个实例,比如调用实例的静态属性不会创建实例。
如何保障我们只能创建一个 GirlFriend 对象
步骤[单例模式-懒汉式]
- 将构造器私有化
- 在类的内部直接创建对象(该对象是 static)
- 提供一个公共的 static 方法,返回对象
- 懒汉式,只有当用户使用 getInstance 时,才返回对象, 后面再次调用时,会返回上次创建的 cat 对象
class Car{
private String name;
//在类加载时创建Car对象,只执行一次
//为了在静态方法中访问需要定义为static
private static Car car;
private Car(String name){
System.out.println("创建一个Car类");
this.name = name;
}
//提供一个公共的静态方法,返回Car对象
public static Car getInstance(){
if(car == null){
car = new Car("lldwb");
}
return car;
}
}
饿汉式 VS 懒汉式
- 二者最主要的区别在于创建对象的时机不同:饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建。
- 一个是加载时创建,一个是使用时创建
- 饿汉式不存在线程安全问题,懒汉式存在线程安全问题。(多线程中可能创建多个对象)
- 饿汉式存在浪费资源的可能。因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费了,懒汉式是使用时才创建,就不存在这个问题。
- 在我们javaSE标准类中,java.lang.Runtime就是经典的单例模式
单例模式的使用场景
- QQ聊天窗口(只会打开一个窗口)
补充
懒汉式中解决线程安全
- 在方法访问修饰符加多线程的同步块(synchronized)
- 换饿汉式
-
结合静态内部类,代码如下
public class People { private People(){} /** * 使用静态内部类来创建一个唯一的外部类实例 */ private static class InnerClass{ // 创建一个唯一的外部类实例 private static final People INSTANCE = new People(); } /** * 对外部提供一个公开的方法获取实例 * @return */ public static People getInstance(){ // 当使用InnerClass时才会加载这个内部类,从而初始化People的实例 // 因为static只会执行一次,所有只有一个People对象 return InnerClass.INSTANCE; } }