单例模式的五种创建方法
单例模式确保只有一个对象,避免重复创建对象
1.饿汉模式(the singleton instance is early created at complie time) 提前创建了对象
package top.freeme.my;
/**
* @author Administrator
* 饿汉式
*/
public class SingleTon {
private static SingleTon singleTon = new SingleTon();
private SingleTon() {
}
public static SingleTon getInstance(){
return singleTon;
}
以空间换时间,故不存在线程安全问题。
由于private static SingleTon singleTon = new SingleTon();语句被static修饰,这个Singleton对象在一开始就被创建了,是线程安全的
2.懒汉式(the singleton instance is lazily created at runtime) 后面在创建对象
package top.freeme.my;
/**
* @author Administrator
* 饿汉式
*/
public class SingleTon2 {
private static SingleTon2 singleTon = null;
private SingleTon2() {
}
public static SingleTon2 getInstance(){
if (singleTon==null){
singleTon = new SingleTon2();
}
return singleTon;
}
}
懒汉模式在方法被调用后才创建对象,以时间换空间,在多线程环境下存在风险。
3.双重锁懒汉模式
package top.freeme.my;
/**
* @author Administrator
* 双检锁
*/
public class SingleTon3 {
//-- 这里需要加volatile关键字,要不然线程不安全
private static volatile SingleTon3 singleTon = null;
private SingleTon3() {
}
public static SingleTon3 getInstance(){
if (singleTon==null){
synchronized (SingleTon3.class){
if (singleTon==null){
singleTon = new SingleTon3();
}
}
}
return singleTon;
}
}
jvm存在乱序执行,因此需要加volatile关键字确保线程安全
具体原理参考
https://blog.csdn.net/mnb65482/article/details/80458571
4.静态内部类模式 推荐使用
package top.freeme.my;
/**
* @author Administrator
* 双检锁
*/
public class SingleTon4 {
private static volatile SingleTon4 singleTon = null;
private SingleTon4() {}
private static class Inner{
private static final SingleTon4 singleTon4= new SingleTon4();
}
public SingleTon4 getInstance(){
return Inner.singleTon4;
}
}
线程安全的,同时也延迟了单例的实例化。但是不能传递参数
5.枚举
package top.freeme.my;
/**
* @author Administrator
* 单例模式枚举
*/
public enum SingleTon5 {;
private static SingleTon singleTon5 = new SingleTon();
public static void main(String[] args) {
SingleTon singleTon5 = SingleTon5.singleTon5;
}
}
参考链接
https://blog.csdn.net/mnb65482/article/details/80458571