单例模式,框架中使用比较多的,开发中较为常用的设计模式。当某种业务需要保证只使用一种实例时,如windows中的任务管理器,永远只能打开一个窗口。
1、饿汉式,线程安全
public class Singleton{
//创建静态变量并进行初始化,并且jvm加载时就会进行实例,保证该实例只有一个
//但是对于多线程而言,这样的效率并不高,造成资源的浪费
private static final instance=new Singleton();
private Singleton(){}//将构造函数访问权限修改成private,即外部无法通过new进行实例化调用
public static Singleton getInstance(){
return instance;
}
}2、懒汉式,线程不安全
//解决了饿汉式的资源浪费的缺点,但是只能在单线程下进行,如果多线程下会不安全
public class Singleton{
//创建静态变量,但不初始化,等待使用时进行初始化
private static Singleton instance=null;
private Singleton(){}
public static Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}3、懒汉式,线程安全
//该线程安全版本,是在初始化方法上加上同步机制synchronized,是的线程安全,但是这种全局同步,会
使得在多线程并发情况下,执行效率不高,故而不推荐
public class Singleton{
private static Singleton instance=null;
private Singleton(){}
private synchronized Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}4、懒汉式,变种,线程安全
//该线程安全版本,是在线程不安全版本上,使用静态块初始化instance实例,通过静态变量jvm初始化规则
静态变量/静态块-非静态变量/构造块-构造函数
public class Singleton{
private static Singleton instance=null;
static {
instance=new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}5、使用静态内部类实现,线程安全【推荐】
public class Singleton{
private static final class SingletonHolder{
private static final Singleton instance=new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
}6、使用枚举,线程安全【推荐】
public class Singleton{
private Singleton(){}
private static Singleton getInstance(){
return SingletonHolder.INSTANCE.getInstance;
}
public enum SingletonHolder{
INSTANCE;
private Singleton instance=null;
SingletonHolder(){
instance=new Singleton();
}
public Singleton getInstance(){
return instance;
}
}
}7、双重校验锁,线程安全【推荐】
public class Singleton{
private static Singleton instance=null;
private Singleton(){}
public static Singleton getInstance(){
synchronized(Singleton.class){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}测试:
public static void main(String[] args) { System.out.println(Singleton.getInstance() == Singleton.getInstance()); System.out.println(Singleton2.getInstance() == Singleton2.getInstance()); System.out.println(Singleton3.getInstance() == Singleton3.getInstance()); System.out.println(Singleton4.getInstance() == Singleton4.getInstance()); System.out.println(Singleton5.getInstance() == Singleton5.getInstance()); System.out.println(Singleton6.INSTANCE == Singleton6.INSTANCE); System.out.println(Singleton7.getInstance() == Singleton7.getInstance()); }
运行结果:
