[JavaEE]浅谈单例模式、wait和sleep的区别。

目录

一、wait和sleep的区别

二、单例模式


一、wait和sleep的区别

        wait是⽤于线程之间的通信的,sleep是让线程阻 塞⼀段时间。唯⼀的相同点就是都可以让线程放弃执⾏⼀段时间。

        (1)wait需要搭配synchronized使⽤,sleep不需要。

        (2)wait是Object的⽅法,sleep是Thread的静态⽅法。

        当有多个wait和一个notify的时候,唤醒的线程是随机的,当有多个notify和一个wait的时候,多出来的notify并不会影响进程。

二、单例模式

        (1)饿汉模式:类加载的同时,创建实例。由于创建操作在加载的时候完成,所以多线程运行的时候不会有线程安全问题。

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

        (2)懒汉模式:类加载的时候不创建实例.第⼀次使⽤的时候才创建实例。懒汉模式不同于饿汉模式,由于不在类加载的时候创建实例,当多线程运行的时候存在几个问题。

                <1>问题一:多线程运行 if 操作容易多个线程同时运行,所以很有可能同时创建了一个实例,而先创建的实力则会消失。

class SignleTonLazy{
    private static SignleTonLazy instance = null;
    private SignleTonLazy(){}
    public static SignleTonLazy getInstance(){
        if(instance == null){
            instance = new SignleTonLazy();
        }
        return instance;
    }
}

        

                <2>问题二:我们可以在第一次if判断前加上锁来确保线程安全问题。但是这么做,会让多个线程同时进行锁的判断等待,会造成大量的时间浪费

class SignleTonLazy{
    public static String loker1  = new String();
    private static SignleTonLazy instance = null;
    private SignleTonLazy(){}
    public static SignleTonLazy getInstance(){
        synchronized (loker1){
            if(instance == null){
                instance = new SignleTonLazy();
            }
        }
        return instance;
    }
}

                <3>问题三:在我们进行if加锁之前,可以嵌套一个if做判断,如果是第一次创建实例再去进行等待。但是这么做仍然有问题,因为在创建实例的时候,JVM的优化可能让指令重排序,会造成先拿到实例地址后进行地址赋值,这就导致拿到的 实例值是错误的,所以我们最后需要加上volatile给要创建的实例,来让JVM最小程度优化指令。

class SignleTonLazy{
    public static String loker1  = new String();
    private static volatile SignleTonLazy instance = null;
    private SignleTonLazy(){}
    public static SignleTonLazy getInstance(){
        if(instance == null){
            synchronized (loker1){
                if(instance == null){
                    instance = new SignleTonLazy();
                }
            }
        }
        return instance;
    }
}

          创建局部变量,处于JVM内存中的“栈”区域中,new 出来变量,处于JVM内存中“堆”区中。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值