单例设计模式(懒汉式or饿汉式)
1 什么是设计模式
- 静态方法和属性的经典使用
- 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己再思考和摸索.
2 什么是单例模式
单例:单个实例
- 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。
- 单例模式有两种方式:1)饿汉式 2)懒汉式;
(保证某一个只能有一个实例,不可以再有第二个实例,比如某一个非常重要的核心类,只使用一次)
3 单例设计模式-饿汉式
步骤如下:
- 构造器私有化(防止用户直接去new)
- 类的内部创建对象;
- 向外暴露一个静态的公共方法。getInstance()
饿汉式:只要类加载,类的属性就创建了,你还没用到呢。很着急!!!!
那么,很自然的想到,饿汉式单例模式会造成资源的浪费。
public class SingleTon01 {
public static void main(String[] args) {
// GirlFriend xh = new GirlFriend("小红");
// GirlFriend xb = new GirlFriend("小白");
//通过方法可以获取对象
GirlFriend instance = GirlFriend.getInstance();
System.out.println(instance);
GirlFriend instance2 = GirlFriend.getInstance();
System.out.println(instance2);
System.out.println(instance == instance2);//T
//System.out.println(GirlFriend.n1);
//...
}
}
//有一个类, GirlFriend
//只能有一个女朋友
class GirlFriend {
private String name;
//public static int n1 = 100;
//为了能够在静态方法中,返回 gf对象,需要将其修饰为static
//對象,通常是重量級的對象, 餓漢式可能造成創建了對象,但是沒有使用.
private static GirlFriend gf = new GirlFriend("小红红");
//如何保障我们只能创建一个 GirlFriend 对象
//步骤[单例模式-饿汉式]
//1. 将构造器私有化
//2. 在类的内部直接创建对象(该对象是static)
//3. 提供一个公共的static方法,返回 gf对象
private GirlFriend(String name) {
System.out.println("構造器被調用.");
this.name = name;
}
public static GirlFriend getInstance() {
return gf;
}
@Override
public String toString() {
return "GirlFriend{" +
"name='" + name + '\'' +
'}';
}
}
3 单例设计模式-懒汉式
存在线程安全问题
package com.yt.singleinstance;
public class SingleTest02 {
public static void main(String[] args) {
Cat instance = Cat.getInstance();
System.out.println(instance);//1540e19d
Cat instance1 = Cat.getInstance();
System.out.println(instance1);//1540e19d
}
}
//希望在程序运行的时候只能创建一个对象
//使用单例模式
class Cat{
private String name;
private static Cat cat;//默认值为null
//步骤:
//1.将类的构造器私有化
//2.定义一个类属性对象,如果是饿汉式就直接new一个对象
//3.定义一个public的静态static方法,返回类对象,
// 懒汉式,在调用时再创建类对象
private Cat(String name) {
this.name = name;
}
public static Cat getInstance(){
if (cat == null){
//如果还没有就创建cat对象,需要时再用
cat = new Cat("xiaomiaomiao");
}
return cat;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
}
4 饿汉式 VS 懒汉式
- 二者最主要的区别在于创建对象的时机不同:饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建。
- 饿汉式不存在线程安全问题,懒汉式存在线程安全问题。(后面学习线程后,会完善一把)
- 饿汉式存在浪费资源的可能。因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费了,懒汉式是使用时才创建,就不存在这个问题。
- 在我们javaSE标准类中,java.lang.Runtime就是经典的单例模式。(饿汉式单例模式)