目录
单例模式:
保证一个类在程序中只存在唯一实例,分为“饿汉”和“懒汉”两种实现方式
饿汉模式:
只是读操作,本身就线程安全
懒汉模式:
有读有写,线程是不安全的
懒汉模式的安全操作:
1.双重if,减少不必要的加锁操作
class SingletonLazy{
//唯一实例
private static SingletonLazy instance=new SingletonLazy();
//获取实例方法
public static SingletonLazy getInstacne(){
if(instance==null){
if(instance==null){
instance=new SingletonLazy();
}
}
return instance;
}
//禁止外部new实例
private SingletonLazy(){}
}
2.加锁,把if和new变成原子(不可拆分)操作
class SingletonLazy{
//唯一实例
private static SingletonLazy instance=new SingletonLazy();
//获取实例方法
public static SingletonLazy getInstacne(){
if(instance==null){
synchronized (SingletonLazy.class){
if(instance==null){
instance=new SingletonLazy();
}
}//两个if虽然紧挨着,但是代码可能不会立马执行,因为中间有个synchronized,
// 加锁可能会阻塞,解除阻塞的时间未知,可长可短
}
return instance;
}
//禁止外部new实例
private SingletonLazy(){}
}
3.使用volatile禁止指令重排序(未装修的毛坯房),保证后续线程拿到的是完整对象
//唯一实例
volatile private static SingletonLazy instance=new SingletonLazy();
4.完整代码
class SingletonLazy{
//唯一实例
volatile private static SingletonLazy instance=new SingletonLazy();
//获取实例方法
public static SingletonLazy getInstacne(){
if(instance==null){
synchronized (SingletonLazy.class){
if(instance==null){
instance=new SingletonLazy();
}//两个if虽然紧挨着,但是代码可能不会立马执行,因为中间有个synchronized,
// 加锁可能会阻塞,解除阻塞的时间未知,可长可短
}
}
return instance;
}
//禁止外部new实例
private SingletonLazy(){}
}
public class demo18 {
public static void main(String[] args) {
//调用的是一个实例
SingletonLazy s1=SingletonLazy.getInstacne();
SingletonLazy s2=SingletonLazy.getInstacne();
System.out.println(s1==s2);
}
}
执行结果: