单例模式

分类专栏:
设计模式

文章标签:
Java自学
设计模式
创建型模式
原创

单例模式

单例模式是Java中最简单的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供一种访问其唯一对象的方式,可以直接访问,不要要实例化该类的对象。

注意:

1)单例类只能有一个实例
2)单例类必须自己创建自己的唯一实例
3)单例类必须给所有其他对象提供这一实例。

创建意图与使用步骤

意图: 一个类仅有一个实例,提供一个访问它的全局访问点
主要解决 : 一个全局使用的类频繁的创建与销毁
何时使用: 当想控制实例数目 节省系统资源时
如何解决: 判断系统是否已有单例 有则返回 无则创建
关键: 构造函数私有

单例模式的几种实现方式

1.懒汉式(线程不安全)

最基本的实现方式 不支持多线程
实例

public class Singleton{

//创建对象
private static Singleton instance;

//构造函数private 这样类就不会被实例化
private  Singleton(){}

//判断是否存在 根据判断是否存在来获取对象
public static Singleton getInstance(){
		if(instance==null){
			instance = new Singleton();
		}
		return instance;
	}
}

2.懒汉式(线程安全)

第一次调用必须初始化 避免内存浪费 加锁导致效率很低
实例

public class Singleton{

    private static Singleton instance;
	
    private Singleton(){}
	
    public static synchronized Singleton getInstance(){
        if (instance==null){
            instance = new Singleton();
        }
        return instance;
    }
}

3.饿汉式(线程安全)

没有加锁 执行效率高 类加载时就初始化 浪费内存 这种方式常用 容易产生垃圾对象
实例

public class Singleton{
    
    private static Singleton instance = new Singleton();
    
    private Singleton(){}
    
    public static Singleton getInstance(){
        
        return instance;
    }
}

4.双重锁(double-checked locking)

双锁机制 安全且在多线程情况下能保持高性能
实例

public class Singleton{

    private volatile static Singleton singleton;

    private Singleton(){}

    public static Singleton getSingleton(){

        if (singleton==null){
            synchronized (Singleton.class){
                if (singleton==null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

5.登记式(静态内部类)

同双重锁功效一样 但实现更加简单 这种方式只适用于静态域
实例

public class Singleton{

    private static class SingletonHolder{
        
        private static final Singleton INSTANCE = new Singleton();
    }
    
    private Singleton(){}
    
    public static final Singleton getInstance(){
        
        return SingletonHolder.INSTANCE;
    }
}

6.枚举

自动支持序列化机制 绝对防止多次实例化 更为简洁
实例

public enum Singleton {
	INSTANCE;

	public void whateverMethod() {
	}
}

建议

一般情况下 不建议使用第1种和第2种懒汉方式
建议使用第3种饿汉方式
只有在要明确实现 lazy loading 效果时 才会使用第 5 种登记方式
如果涉及到反序列化创建对象时 可以尝试使用第 6 种枚举方式
如果有其他特殊的需求 可以考虑使用第 4 种双检锁方式
  • 作者:潘震
  • 版权声明:自由转载-非商用-非衍生-保留署名(创意共享3.0许可证)
  • 评论

    pz
    测试
    留言