什么是单例设计模式
单例设计模式(Singleton Design Pattern),就是一个类只能被实例化一次,再通俗一点就是只能被new一次。new出来这个对象,被全局共用。
单例设计模式的作用
要保证全局只有一份的时候(不管这一份是什么,重点是一份),这时就可以使用单例,比如实现一个全局唯一的资源加载类,资源加载一般只要一个地方来加载就可以了。
懒汉式单例和饿汉式单例
我们先来学习两种比较简单的单例,懒汉式单例和饿汉式单例,我们看完代码再来分析两种的区别。
懒汉式单例:
package com.itzhimei.study.design.singleton;
/**
* www.itzhimei.com
* 饿汉式单例
*/
public class Singleton1 {
private static Singleton1 singleton = new Singleton1();
private Singleton1() {
}
public static Singleton1 getInstance() {
return singleton;
}
}
懒汉式单例测试:
package com.itzhimei.study.design.singleton;
/**
* www.itzhimei.com
*/
public class Client1 {
public static void main(String[] args) {
//提示错误:'Singleton1()' has private access in 'com.itzhimei.study.design.singleton.Singleton1'
//Singleton1 s1 = new Singleton1();
Singleton1 s1 = Singleton1.getInstance();
Singleton1 s2 = Singleton1.getInstance();
if(s1 == s2) {
System.out.println("是一个对象");
} else {
System.out.println("不是一个对象");
}
}
}
输出结果:
是一个对象
你也可以多执行几次测试代码,或者将测试代码放到循环里执行一定次数,看看执行结果。
饿汉式单例:
package com.itzhimei.study.design.singleton;
/**
* www.itzhimei.com
* 懒汉式单例
*/
public class Singleton2 {
private static Singleton2 singleton = null;
private Singleton2() {
}
public synchronized static Singleton2 getInstance() {
if(singleton == null) {
singleton = new Singleton2();
}
return singleton;
}
}
懒汉式单例测试:
package com.itzhimei.study.design.singleton;
/**
* www.itzhimei.com
*/
public class Client2 {
public static void main(String[] args) {
//提示错误:'Singleton2()' has private access in 'com.itzhimei.study.design.singleton.Singleton2'
//Singleton2 s1 = new Singleton2();
Singleton2 s1 = Singleton2.getInstance();
Singleton2 s2 = Singleton2.getInstance();
if(s1 == s2) {
System.out.println("是一个对象");
} else {
System.out.println("不是一个对象");
}
}
}
输出结果:
是一个对象
懒汉式和饿汉式的区别在于,懒汉式是需要使用这个单例类时,才判断是否存在实例,不存在则创建返回实例,存在则直接返回。
这里的判断就用到了synchronized来做多线程同步,防止因为并发而造成了多个实例,就不是单例了,使用了synchronized对性能由一些影响。
而饿汉式是类的字节码被加载到JVM的时候,就会创建实例,并不需要做同步处理,缺点就是不管用不用,都直接加载到内存,有可能会造成内存浪费。
上面的的两种单例,是最简单的单例写法,也是最应该掌握的。单例还有多种写法,在实际项目和框架中,应用也非常广泛,我们下一届再来一起学习。