单例模式

单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点

通常来讲可以让一个全局变量使得一个对象被访问,但是它不能阻止你实例化多个对象,一个最好的方法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法

单例模式(Singleton)结构图


Singleton类:定义一个GetInstance操作,允许客户访问它的唯一实例。GetInstance是一个静态方法,主要负责创建自己的唯一实例

单例模式的好处:除了保证唯一实例外,还包括单例模式因为Singleton类封装了它的唯一实例,这样它就可以严格的控制客户怎样访问它以及何时访问 它,就是对唯一实例的受控访问

懒汉模式

package singleton;

public class Singleton {
	private static Singleton instance;
	
	/**
	 * 构造方法为private,堵死了外界利用new 创建实例的可能性
	 */
	private Singleton(){
		
	}
	//该方法是获得本类实例的唯一全局访问点
	public static Singleton GetInstance(){
		if(instance == null){		//若实例不存在,则new一个新实例,否则返回已有的实例
			instance = new Singleton();
		}
		return instance;
	}
}

客户端

package singleton;

public class Clinet {
	public static void main(String[] args) {
		Singleton t1 = Singleton.GetInstance();
		Singleton t2 = Singleton.GetInstance();
		
		if(t1 == t2){
			System.out.println("两个对象是相同的实例");
		}
	}
}

多线程的单例

懒汉模式下的单例没有考虑线程安全的问题,在多线程下是线程不安全的,多个线程同时访问Singleton类,调用GetInstance()方法,会有可能创建多个实例

此时应该创建一个进程锁synchronized,,synchronized可以确保当一个线程位于代码的临界区时,另外的线程不进入临界区。其他线程试图进入锁定的代码时,它会一直等待,直到该对象被释放。

GetInstance()方法加同步锁

public static synchronized Singleton GetInstance(){
		if(instance ==	 null){		//若实例不存在,则new一个新实例,否则返回已有的实例
			instance = new Singleton();
		}
		return instance;
	} 

双重锁

同步锁保护,固然保证单例,但是造成性能低,因此可以使用双重加锁检查机制

双重加锁机制:方法GetInstance()前不加同步锁,进入方法后,先检查实例是否存在,之后再进入加锁的同步块,进入同步块后,再检查实例是否存在,根据情况来判断是否创建对象,这样减少了多次在同步情况下加锁所消耗的时间。

public static  Singleton GetInstance(){
		if(instance ==	 null){		
			synchronized (Singleton.class) {
				if(instance == null){
					instance = new Singleton();
				}
			}
			
		}
		return instance;
	}

饿汉模式

// 饿汉模式
public class Singleton {
    // 私有构造
    private Singleton() {}

    private static Singleton instance = new Singleton();

    // 静态工厂方法
    public static Singleton getInstance() {
        return instance;
    }
}

饿汉模式的单例在类被加载的时候就被创建,保证了单列,而且本身是线程安全的

懒汉模式和饿汉模式的区别:懒汉模式是延时加载,是在需要的时候才创建对象,而饿汉模式在虚拟机启动的时候就会创建,饿汉模式无需关注多线程问题


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值