5种Java实现单例模式的方法介绍
在Java编程中,当我们希望某个类只有一个实例存在时,就需要使用单例模式。下面介绍5种Java实现单例模式的方法:
方法1:饿汉式单例模式
这种方式基于classloder机制避免了多线程的同步问题,不过instance在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用getInstance方法,但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到lazy loading的效果。
示例:
public class Singleton1 {
private static Singleton1 instance = new Singleton1();
private Singleton1(){}
public static Singleton1 getInstance(){
return instance;
}
}
方法2:懒汉式单例模式(线程不安全)
这种方法实现起来很简单,只需要在第一次调用的时候实例化对象即可,但是在多线程下是不安全的。
示例:
public class Singleton2 {
private static Singleton2 instance;
private Singleton2(){}
public static Singleton2 getInstance(){
if(instance == null){
instance = new Singleton2();
}
return instance;
}
}
方法3:懒汉式单例模式(线程安全,效率低)
这种方法考虑到了线程安全,但是效率很低,因为整个方法被synchronized所修饰,因此每次调用getInstance时都要对对象加锁,试图通过减小锁的范围提高效率,结果往往会出现错误或不可靠的情况。
示例:
public class Singleton3 {
private static Singleton3 instance;
private Singleton3(){}
public static synchronized Singleton3 getInstance(){ //加锁
if(instance == null){
instance = new Singleton3();
}
return instance;
}
}
方法4:双检锁/双重校验锁(DCL,即double-checked locking)
这种方法致力于解决懒汉式单例模式(线程安全,效率低)的效率问题,只有在第一次创建对象的时候才会加锁,达到了又能解决线程安全问题,又能提高效率的目的。
示例:
public class Singleton4 {
private volatile static Singleton4 instance;// volatile:禁止指令重排序
private Singleton4(){}
public static Singleton4 getInstance(){
if(instance == null){
synchronized (Singleton4.class){ //加锁
if(instance == null){
instance = new Singleton4();
}
}
}
return instance;
}
}
方法5:静态内部类单例模式
这种方法也是懒汉式单例模式的一种形式,但是相对于其他方法而言更为安全高效。当Singleton5类被载入JVM时,其内部类SingletonHolder并不会被初始化。只有当调用getInstance方法时,才会加载SingletonHolder类,从而实例化Singleton5。同时,由于SingletonHolder是静态的,所以JVM不会重新加载。
示例:
public class Singleton5 {
private Singleton5(){}
private static class SingletonHolder{
private static final Singleton5 INSTANCE = new Singleton5();
}
public static Singleton5 getInstance(){
return SingletonHolder.INSTANCE;
}
}
以上5种方法各有优缺点,根据不同的情况选择合适的单例模式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现单例模式的五种方法介绍 - Python技术站