单例模式
单例模式是最简单也是常见的Java设计模式之一。使用该模式的类需要自己负责创建自己的对象,并且只能有单个实例对象被创建。
该设计模式有以下三个特点:
- 单例类只能有一个实例对象
- 单例类自身负责创建实例对象
- 单例类必须给其它对象提供获取其实例对象的方法
当我们需要控制类的实例对象数量和节约资源开销的时候,可以考虑使用单例模式。下面是单例模式的几种实现
1. 懒汉式,线程不安全
public class Singleton {
//懒汉式,线程不安全
private static Singleton singleton;
private Singleton(){
}
public static Singleton getInstance(){
if (singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
这种实现方式,当有多个线程同时使用调用该单例类的getInstance()方法时,可能会创建多个实例。所以这种实现方式时线程不安全的。
2. 饿汉式,线程安全
public class Singleton {
//饿汉式,线程安全
//利用类加载机制避免同步的问题,是线程安全的
private static Singleton singleton = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return singleton;
}
}
3. 懒汉式,线程安全
public class Singleton {
//懒汉式,线程安全
//利用synchronized同步锁,解决了多线程的安全问题
private static Singleton singleton;
private Singleton(){
}
public synchronized static Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
这种利用synchronized关键字解决了多线程安全问题,但是效率低下。
4.双重锁
public class Singleton {
//懒汉式,双重锁机制
//加volatile避免指令重排
//创建对象的过程分为3步:
//1、分配内存
//2、初始化实例对象
//3、指向分配的内存地址
//假设 A 线程执行了1和3,还没有执行2
//此时此刻,另个一线程B调用getInstance()方法,则会直接返回NULL。
//使用volatile避免指令重排
private volatile static Singleton singleton;
private Singleton(){
}
public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
4.登记式
public class Singleton {
//该方式与第二种饿汉式方法的区别是,该方式避免了Singleton类被加载就初始化其实例对象.
private static class SingleHelper{
private static final Singleton singleton = new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return SingleHelper.singleton;
}
}
本文详细解析单例模式的原理,比较懒汉式、饿汉式、双重锁和登记式实现,强调线程安全的重要性。了解如何在Java中控制实例数和优化资源利用。
976

被折叠的 条评论
为什么被折叠?



