1、单例,模式
单例模式属于创建型模式的一种,应用于保证一个类仅有一个实例的场景下,并且提供了一个访问它的全局方法
- 单例模式的特点:从系统启动到终止,整个过程只会产生一个实例。
- 单例模式常用写法:懒汉式,饿汉式,注册式,序列化式。
2、懒汉式和饿汉式概念
懒汉式:在需要使用对象的时候,再创建对象,不会提前创建
只有再调用获取实例的时候,才会去初始化实例对象
懒加载:是
是否线程安全:否
备注:可以在静态方法上面添加synchronized关键字,实现线程安全
饿汉式:不管对象使用与否,都会提前把对象创建准备好,方便使用.
类加载时即创建对象,线程安全
优点:执行效率高
缺点:类加载时就初始化,浪费内存资源,懒加载:无
3、实现步骤
1、都声明私有构造方法,使得在类的外部不能调用此方法,限制产生多个对象
2、对外部提供静态调用方法,将创建的对象返回,只能通过类来调用
4、代码
- 懒汉式
懒汉式:在需要使用对象的时候,再创建对象,不会提前创建。
package com.hx;
/*
懒汉式:
在需要使用对象的时候,再创建对象,不会提前创建。
*/
public class Singleton1 {
//私有构造方法
private Singleton1() {
System.out.println("懒汉式的无参数构造方法,被调用了!");
}
//定义静态变量,先不建立对象
private static Singleton1 singleton = null;
//懒汉式:定义创建对象的方法
public static synchronized Singleton1 getInstance() {
//先判断是否为空
if (singleton == null) {
//懒汉式做法,如果未null,才进行创建
singleton = new Singleton1();
}
//返回创建好的对象
return singleton;
}
}
- 饿汉式
饿汉式:不管对象使用与否,都会提前把对象创建准备好,方便使用
package com.hx;
/*
饿汉式:
不管对象使用与否,都会提前把对象创建准备好,方便使用
*/
public class Singleton2 {
//定义公开的构造方法
private Singleton2() {
System.out.println("饿汉式的无参构造方法,被调用了!");
}
//定义静态变量接收创建的对象
private static Singleton2 singleton = new Singleton2();
//饿汉式:定义静态方法返回已经创建好的对象
public static Singleton2 getInstance() {
//返回已经创建好的对象
return singleton;
}
}
- 测试类创建对象
package com.hx;
public class TestSingleton {
public static void main(String[] args) {
//使用类名.方法名()创建对象
//懒汉式
Singleton1 singleton1 = Singleton1.getInstance();
System.out.println(singleton1);
//饿汉式
Singleton2 singleton2 = Singleton2.getInstance();
System.out.println(singleton2);
}
}
5、懒汉式和饿汉式的区别
-
1、实例化方面:
- 懒汉式默认不会实例化,外部什么时候调用什么时候new。
- 饿汉式在类加载的时候就实例化,并且创建单例对象。
-
2、线程安全方面:
- 饿汉式线程安全 ,在线程还没出现之前就已经实例化了,因此饿汉式线程一定是安全的。
- 懒汉式线程不安全, 因为懒汉式加载是在使用时才会去new 实例的,那么去new的时候是一个动态的过程,是放到方法中实现的,如果这个时候有多个线程访问这个实例,这个时候实例还不存在,还在new,就会进入到方法中,有多少线程就会new出多少个实例。一个方法只能return一个实例,那最终return出哪个呢?是不是会覆盖很多new的实例?这种情况当然也可以解决,那就是加同步锁,避免这种情况发生) 。
-
//懒汉式:定义创建对象的方法 public static synchronized Singleton1 getInstance() { //先判断是否为空 if (singleton == null) { //懒汉式做法,如果未null,才进行创建 singleton = new Singleton1(); } //返回创建好的对象 return singleton; }
-
3、执行效率上:
- 饿汉式没有加任何的锁,因此执行效率比较高。
- 懒汉式一般使用都会加同步锁,效率比饿汉式差。
-
4、性能上:
- 饿汉式在类加载的时候就初始化,不管你是否使用,它都实例化了,所以会占据空间,浪费内存。
- 懒汉式什么时候需要什么时候实例化,相对来说不浪费内存。