1.简介
保证一个类仅有一个实例, 并提供一个访问它的全局访问点。让类自身负责保存它的唯一实例。 这个类可以保证没有其他实例可以被创建(通过截取创建新对象的请求 ), 并且它可以提供一个访问该实例的方法
2.实现
2.1 懒汉式,线程不安全
package com.zw.designpatterns.singleton;
/*
* 这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
* 这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
*/
public class Demo1 {
private static Demo1 demo1;
private Demo1() {
}
public static Demo1 getDemo1() {
if (demo1 == null) {
demo1 = new Demo1();
}
return demo1;
}
}
2.2 懒汉式,线程安全
第一种不能保证线程安全,我们可以通过加锁的方式实现线程安全,缺点是因为加了锁影响了性能。
package com.zw.designpatterns.singleton;
/*
* 这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
* 这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
*/
public class Demo1 {
private static Demo1 demo1;
private Demo1() {
}
public static synchronized Demo1 getDemo1() {
if (demo1 == null) {
demo1 = new Demo1();
}
return demo1;
}
}
2.3 饿汉式,线程安全
初始化就创建实例。相比于第二种,没有加锁,执行效率会提高,缺点初始化就创建即便没有使用,浪费内存。
package com.zw.designpatterns.singleton;
public class Demo1 {
private static Demo1 demo1 = new Demo1();
private Demo1() {
}
public static Demo1 getDemo1() {
return demo1;
}
}
2.4 双检锁
在多线程情况下能保持高性能
package com.zw.designpatterns.singleton;
public class Demo3 {
// 加上volatile是为了保证instance = new Demo3()这个过程没有完成的时候,
// 其它线程执行if (instance == null) 又去执行instance = new Demo3()
private static volatile Demo3 instance;
private Demo3() {
}
public static Demo3 getInstance() {
if (instance == null) {
synchronized (Demo3.class) {
if (instance == null) {
instance = new Demo3();
}
}
}
return instance;
}
}