单例模式的写法

单例模式是一种经典的设计模式,在校招阶段主要考察两个设计模式:

1.单例模式  2.工厂模式

设计模式需要大家有一定的开发经验的积累,才好理解~~

单例 => 单个实例(instance)  对象 (类的实例,就是对象)

单例:一个程序中,某个类,只创建出一个实例(一个对象),不能创建多个对象~~

Java中的单例模式,借助Java语法,保证某个类,只能创建出一个实例,而不能new多次

2.在Java语法中,如何做出单例模式的实现~~

Java中实现单例模式有很多写法,目前我们主要说两种~~

2.1 饿汉模式

2.2 懒汉模式

例如计算机中的例子:打开一个硬盘的文件,读取文件内容,并显示出来~~

饿汉:把文件所有内容都读到内存中,并显示

懒汉模式:只把文件读一小部分,把当前屏幕填充上,如果用户翻页了,再读其他文件,如果不翻页,就生了~~

package threading;
//把这个类设定成单例的~~
class Singleton{
    //唯一实例的本体
    private static Singleton instance = new Singleton();

    //获取到实例的方法
    public static Singleton getInstance() {
        return instance;
    }
    //禁止外部new实例
    private Singleton(){}
}

public class ThreadDemo17 {
    public static void main(String[] args){
        //此时s1和s2是同一个对象
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        //Singleton s3 = new Singleton();
    }

}

 private static Singleton instance = new Singleton();

instance 就是唯一的实例了~~

被static修饰,该属性是类的属性~~(类对象上)

JVM中,每个类的类对象只有唯一一份,类对象里的这个成员,自然也是唯一一份了~~

Singleton s3 = new singleton();

c此处需要把new操作给禁止掉!!

把该类的构造方法设为private即可!!

另一方面,单例模式,有一种实现方式,也可以保证,反射安全

wait notify 需要搭配锁对象

单例模式:

懒汉模式来实现单例:核心思想,非必要不创建

懒汉模式实现单例

package threading;
//通过懒汉模式实现一下单例模式
class SingletonLazy{
    volatile private static SingletonLazy instance = null;

    public static SingletonLazy getInstance() {
        //这个条件,判定是否加锁,如果对象已经有了,就不必加锁了,此时本身就是线程安全的
        if(instance == null) {
            synchronized(SingletonLazy.class) {
                if(instance == null){
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }
    private SingletonLazy(){}

}

public class ThreadDemo18 {
    public static void main(String[] args) {
        SingletonLazy s1 = SingletonLazy.getInstance();
        SingletonLazy s2 = SingletonLazy.getInstance();
        System.out.println(s1 == s2);
    }
}

饿汉模式的代码实现

class Singleton {
//唯一实例的本体
private static Singleton instance = new Singleton();
//获取到实例的方法
public static Singleton getInstance() {return instance;}
  //禁止外部new实例
private Singleton() {}
}

 饿汉模式,认为线程是安全的~~

如何解决上述线程安全问题呢  加锁

public static SingletonLazy getInstance() {
Sychronized (SingletonLazy.class) {
  if(instance == null) {
  instance = new SingletonLazy();
   }
 }
return instance;
}

保证判定和new是一个原子操作

加锁其实是一个比较低的操作

(加锁就可能涉及到阻塞等待 )  非必要不加锁~~

其实,此处的线程不安全,只出现在首次创建对象这里,一旦对象new好了,后续调用getInstance,就 只是单纯的读操作,就没有线程安全问题,就没必要加锁了!!

public static singletonLazy getInstance() {
//这个条件,判定是否要加锁,如果对象已经有了,就不毕加锁了
  if(instance == null() {
 sychronized (SingletonLazy.class) {
  if(instance == null) {
instance = new SingletonLazy();
    }
  }
}
 return instance;
}

虽然两个条件相同,但是如果调用的时间间隔长了,结果也可能会不同!!

3.指令重排序

这个操作,可能触发,指令重排序~~

1.创建内存

3.把内存地址,付给引用

2.调用构造方法

(t2将错就错)

改这个问题加 : volatile

小结:

单例模式,线程不安全问题

饿汉模式:天然就是安全的,只是读操作

懒汉模式:不安全的,有读就有写~~

1.加锁:把if和new变成原子操作

2.双重if,减少不必要的加锁操作

3.使用volatile禁止指令重排序,保证后续线程肯定拿到的是完整对象 

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值