常见的单例模式的实现有五种,其中一种是饿汉式,四种是懒汉式。
- 1.饿汉式:不存在线程安全问题。但不管使不使都会占用内存空间,造成内存利用率降低。
package com.zx.singleton;
public class Singleton1 {
private Singleton1(){};
private static Singleton1 instance=new Singleton1();
public static Singleton1 getInstance(){
return instance;
}
}
- 2.懒汉式的第一种:最简单,存在线程安全问题,不使用。
package com.zx.singleton;
public class Singleton2 {
private Singleton2(){};
private static Singleton2 instance;
public static Singleton2 getInstance(){
if(instance==null){
instance=new Singleton2();
}
return instance;
}
}
- 3.懒汉式的第二种:解决了线程安全问题。其中volatile防止重排序,Sychroniezd加锁。但存在的问题是Sychroniezd加在整个方法上导致运行效率较低。
package com.zx.singleton;
public class Singleton3 {
private Singleton3(){};
private static volatile Singleton3 instance;
public static synchronized Singleton3 getInstance(){
if(instance==null){
instance=new Singleton3();
}
return instance;
}
}
- 4.懒汉式的第三种:不存在线程安全问题。解决了上一种的问题。存在的问题就是加锁降低效率。
package com.zx.singleton;
public class Singleton4 {
private Singleton4(){};
private static volatile Singleton4 instance;
public static Singleton4 getInstance(){
if(instance==null){
synchronized (Singleton4.class) {
if(instance==null){
instance=new Singleton4();
}
}
}
return instance;
}
}
- 5.懒汉式的第四种:使用静态内部类,解决线程安全问题,同时不使用锁提高效率。
内部类时延时加载的,也就是在第一次使用时才加载,不使用就不加载,所以可以很好的实现懒汉式单例模式。
package com.zx.singleton;
public class Singleton5 {
private Singleton5(){};
private static class Sub{
private final static Singleton5 instance=new Singleton5();
}
public static Singleton5 getInstance(){
return Sub.instance;
}
}
- 6.枚举实现单例模式
功能完整、使用简洁、无偿地提供了序列化机制、在面对复杂的序列化或者反射攻击时仍然可以绝对防止多次实例化。
枚举如何保证序列化单例:Java规范中规定,每一个枚举类型极其定义的枚举变量在JVM中都是唯一的,因此在枚举类型的序列化和反序列化上,Java做了特殊的规定。在序列化的时候Java仅仅是将枚举对象的name属性输出到结果中,反序列化的时候则是通过 java.lang.Enum 的 valueOf() 方法来根据名字查找枚举对象(即通过name查找枚举对象,并未真正对枚举对象做序列化)。
public class EnumSingleton{
private EnumSingleton(){}
public static EnumSingleton getInstance(){
return Singleton.INSTANCE.getInstance();
}
private static enum Singleton{
INSTANCE;
private EnumSingleton singleton;
private Singleton(){
singleton = new EnumSingleton();
}
public EnumSingleton getInstance(){
return singleton;
}
}
}`