1.什么是单例模式
在某些情况下,有些对象只需要一个就可以了,即每个类只需要一个实例。简单来说,单例模式的作用就是保证在整个程序的生命周期中,任何一个时刻,单例类的实例都只存在一个(当然也可以不存在)。
2.全局变量和单例模式的区别
- 全局变量是对一个对象的静态引用,全局变量确实可以提供单例模式实现的全局访问整个功能,但是它并不能保证应用程序中只有一个实例;
- 编码规范也明确指出应该要少用全局变量,因为过多使用全局变量,会造成代码难度。
- 全局变量并不能实现继承(虽然单例模式在继承上也不能很好的处理,但是还是可以实现继承的)。而单例模式在类中保存了它的唯一实例——这个类,它可以保证只能创建一个实例,同时它还提供了一个访问该唯一实例的全局访问点。
3.如何保证对象唯一?
- 为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象
- 还为了让其他程序有该类对象访问,只好在本类中,自定义一个对象
- 为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式
4.这三步怎么用代码体现呢?
- 将构造函数私有化
- 在类中创建一个本类对象
- 提供一个方法可以获取到该对象
package 饿汉式单例设计模式;
/**
* @BelongsProject: untitled
* @BelongsPackage: 饿汉式单例设计模式
* @Author: mcc
* @CreateTime: 2020-08-24 07:59
* @Description:
*/
class Singleton {
/**
* 2.自己new对象
* 4.由于getSingleton方法被声明为static,静态只能调用静态
* 所以声明类对象也为static
*/
private static Singleton singleton = new Singleton();
/**
* 1.构造函数私有化
*/
private Singleton() {
}
/**
* 3.提供一个全局访问点。
* 声明为static是为了类外部在调用getSingleton方法
* 时不必创建对象,用类即可调用
*
* @return
*/
public static Singleton getSingleton() {
return singleton;
}
}
public class SingletonTest {
public static void main(String[] args) {
Singleton s1 = Singleton.getSingleton();
Singleton s2 = Singleton.getSingleton();
System.out.println(s1 == s2);//true
}
}
注: 对于事物该怎么描述,还怎么描述。当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。
5.特点
- 构造函数私有化
- 外部无法产生新的实例化对象
- 只能通过static方法取得实例化对象
6.懒汉式单例(对象延时加载)
package 懒汉式单例设计模式;
/**
* @BelongsProject: untitled
* @BelongsPackage: 懒汉式单例设计模式
* @Author: mcc
* @CreateTime: 2020-08-24 08:14
* @Description: 存在线程安全问题
*/
class Singleton {
/**
* 2.声明当前类对象,没有初始化
* 4.由于getSingleton方法被声明为static,静态只能调用静态
* 所以声明类对象也为static
*/
private static Singleton singleton = null;
/**
* 1.构造函数私有化
*/
private Singleton() {
}
/**
* 3.提供一个全局访问点。
* 返回对象时要判断Singleton是否已经存在对象,避免每次调用getSingleton方法
* 都要重新new一次Singleton对象
*
* @return
*/
public static Singleton getSingleton() {
if (singleton == null) {
singleton = new Singleton();
return singleton;
}
return singleton;
}
}
public class SingletonTest {
public static void main(String[] args) {
Singleton s1 = Singleton.getSingleton();
Singleton s2 = Singleton.getSingleton();
System.out.println(s1 == s2);
}
}
package 同步机制的懒汉式;
/**
* @BelongsProject: untitled
* @BelongsPackage: 懒汉式单例设计模式
* @Author: mcc
* @CreateTime: 2020-08-24 08:14
* @Description:使用同步机制将懒汉式改为线程安全的
*/
class Singleton {
/**
* 2.声明当前类对象,没有初始化
* 4.由于getSingleton方法被声明为static,静态只能调用静态
* 所以声明类对象也为static
*/
private static Singleton singleton = null;
/**
* 1.构造函数私有化
*/
private Singleton() {
}
/**
* 3.提供一个全局访问点。
* 返回对象时要判断Singleton是否已经存在对象,避免每次调用getSingleton方法
* 都要重新new一次Singleton对象
*
* @return
*/
public static Singleton getSingleton() {
if (singleton == null){
synchronized (Singleton.class){
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
public class SingletonTest {
public static void main(String[] args) {
Singleton s1 = Singleton.getSingleton();
Singleton s2 = Singleton.getSingleton();
System.out.println(s1 == s2);
}
}
7.两种单例模式的区别
- 饿汉式:线程安全,但对象的加载时间过长
- 懒汉式:目前写法线程不安全,对象延时加载