1、饿汉式
public class SingletonInstance{
private static final SingletonInstance instance = new SingletonInstance();
private SingletonInstance(){ }
public static SingletonInstance getInstance(){
return instance ;
}
}
在类加载时就创建对象,可以确保单理对象的唯一性,但如果整个过程不使用,会造成资源浪费。
2、懒加载
public class SingletonInstance{
private static SingletonInstance instance = null;
private SingletonInstance(){ }
public static SingletonInstance getInstance(){
if(instance == null){
instance = new SingletonInstance()
}
return instance ;
}
}
懒加载的方式不会造成资源浪费,但却带来了线程安全问题,在互联网的高并发情况下,可能比资源浪费还要严重。但可以进行优化,避免线程安全问题。
2.1)加锁懒汉式
对于多线程并发带来的安全问题,我们可以使用加上线程同步锁(synchronized关键字)来解决。
public class SingletonInstance{
private static SingletonInstance instance = null;
private SingletonInstance(){ }
public static synchronized SingletonInstance getInstance(){
if(instance == null){
instance = new SingletonInstance()
}
return instance ;
}
}
加锁synchronized后可以解决线程安全的问题,可以进一步优化如下
2.2)双重判断锁定的懒汉式
public class SingletonInstance{
private static volatile SingletonInstance instance = null;
private SingletonInstance(){}
public static SingletonInstance getInstance(){
if(instance == null){
synchronized(SingletonInstance.class){
if(instance == null){
instance = new SingletonInstance()
}
}
}
return instance;
}
}
当instance不为空时,直接返回,不用加锁和重新创建了,可以减少加锁次数,提高性能。
3、静态内部类(IoDH)
饿汉式单例类不能实现延迟加载,不管用不用都始终占据内存;懒汉式单例类线程安全控制烦琐,而且性能受影响。
public class SingletonInstance{
private SingletonInstance(){ }
public static SingletonInstance getInstance(){
return SingletonInstanceHolder.instance ;
}
static class SingletonInstanceHolder{
private static final SingletonInstance instance = new SingletonInstance ();
}
}
静态内部类能实现延迟加载的原因:Java内部静态类在调用时才加载(懒加载)。
通过使用IoDH,既可以实现延迟加载,又可以保证线程安全,不影响系统性能。缺点是与编程语言本身的特性相关,很多面向对象语言不支持IoDH。