Java单例模式详解,用代码带你解读

1.单例模式原理

单例模式:确保一个类最多只有一个实例,并提供一个全局访问点。
代码示例:

public class Test {
	
	public static class Abc
	{
		public Abc() {
		};
	}
	
	public class Cbd
	{
		public Cbd()
		{
			Abc n1,n2;
			n1=new Abc();
			n2=new Abc();
		}
	}
	
	public static void main(String[] args) {
		
		Abc n1,n2;
		
		n1=new Abc();
		n2=new Abc();
		System.out.println(n1+"~~~~~"+n2);
	}
}

打印结果:
存放地址
上边这个打印结果同时也反映了Cbd类中的构造方法内n1和n2的地址也是不同的,所以这种结构往往不能够实现单例。
代码示例对比:

public class Abc{
		private Abc() {   //私有化构造方法
		};
		......
	}

如果一个类的构造方法使用private修饰,那么这个类就无法被这个类以外的其他类所实例化,通俗点讲就是在这个类以外的其他类中无法直接new这个类,同时就满足了类以外的其他类不会创建出这个类的多个类对象。那么要想创建这个类的实例只能让这个类自己实例化自己,通俗讲就是自己去new自己。
经典单例模式代码示例:

public class Singleton {
	
	private static Singleton uniqeInstance=null;
	
	private Singleton(){
		
	};
	
	public static Singleton getInstance(){
		if(uniqeInstance==null){
			uniqeInstance=new Singleton();
		}
		return uniqeInstance;
		
	}

}

到这里单例模式的原理思想就讲完了。

2.单例模式

2.1懒汉式写法及线程安全优化写法

懒汉式顾名思义“比较懒”就是到了用的时候再去创建,用的时候才去检查有没有实例,如果有则返回,没有则新建。
懒汉式经典写法:

public class Singleton {
	
	private static Singleton uniqeInstance=null;
	
	private Singleton(){         //私有化构造方法
		
	};
	
	public static Singleton getInstance(){
		if(uniqeInstance==null){        //判断实例是否存在,不存在则创建,否则直接返回
			uniqeInstance=new Singleton();
		}
		return uniqeInstance;
		
	}

}

弊端:多线程的情况下,假设该类还未实例化,两个线程同时进入了getInstance()方法,第一个线程进入了if代码块,在第一个线程正在创建但还未创建完该实例的时候,此时第二个线程也进入了if代码块,那么这时两个线程分别创建了该实例,即创建了两个实例。所以这种写法是非线程安全的。
懒汉式线程安全优化后写法:

public class Singleton {
	
private static Singleton uniqeInstance=null;
	
	private Singleton(){         //私有化构造方法
		
	};
	
	public static synchronized Singleton getInstance(){
		if(uniqeInstance==null)
		{
			uniqeInstance=new Singleton();
		}
		return uniqeInstance;
		
	}
}

为了保证线程安全则在方法上边追加synchronized同步锁。
弊端:synchronized同步锁是非常消耗资源的。

2.2饿汉式

饿汉式不言而喻“比较勤”,不管是否使用实例,该实例都会在初始化时提前创建好,留作备用。
优点:无线程安全问题。
缺点:盲目创建浪费了资源。

private static Singleton uniqeInstance=new Singleton();
	
	private Singleton(){     //私有化构造方法
		
	};
	
	public static Singleton getInstance(){
		return uniqeInstance;
	}
}

3.单例模式优化

3.1双重检查加锁(双检锁)

public class Singleton {
	
private volatile static Singleton uniqeInstance=null;
	
	private Singleton(){     //私有化构造方法
		
	};
	
	public static Singleton getInstance(){
		if(uniqeInstance==null){ //第一个判断,第一重检查
			synchronized (Single.class) {  //加锁
				if(uniqeInstance==null){  //第二个判断,第二重检查
					uniqeInstance=new Singleton();
				}
			}
		}
		return uniqeInstance;
	}
}

假设对象还未实例化,多线问题像之前的那样,两个线程同时又进入了第一个if代码块,但是两个线程遇到synchronized ()方法,只有先拿到Single对象的线程才可以进入方法内部执行第二个if代码块。这样等Singleton对象被第一个线程实例化后,此后的所有线程将不再执行所有if内部的代码块,因为此时uniqeInstance已不为空,且synchronized方法只执行了一次,大大节省了资源。
优点:这种写法确保了线程安全还又节省了资源。

细品你终会有所收获!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值