单例模式 饿汉模式 懒汉模式 多线程(3)

package Lesson4;
//面试  线程安全
//单例
public class SingleTon {
    //返回单例实例   饿汉模式
    private  SingleTon(){
        //一定要写出来,不能在外部new对象 写成private
    }
    //饿汉模式
    private  static final SingleTon SINGTON=new SingleTon();
    public static SingleTon getInstance(){
        return SINGTON;
    }
    //懒汉模式
    private static volatile SingleTon SINGTON2=null;
    public  static SingleTon getInstance2(){
        //开始判断就不安全了,两个线程都会实例化,返回不同的对象
        if(SINGTON2==null){
            //多个线程可以同时进入这行判断代码判断,都判断为null
            SINGTON2=new SingleTon();
        }
        return SINGTON2;
    }
    //多线程的话有可见性问题,第二个线程判断是否为null,可能已经不为null了

    //保证线程安全性
    public synchronized static SingleTon getInstance3(){
        //开始判断就不安全了,两个线程都会实例化,返回不同的对象
        if(SINGTON2==null){
            //多个线程可以同时进入这行判断代码判断,都判断为null
            SINGTON2=new SingleTon();
        }
        return SINGTON2;
    }
    public static SingleTon getInstance4(){
        if(SINGTON2==null){
            //加volatile从主内存中读
            synchronized (SingleTon.class){
                //这块代码块的原子性
                /*可以分解成三步操作
                 1.分配对象内存空间
                 2.执行对象初始化
                 3.把对象给引用
                4.可能重排序132,3在2之前执行了,就返回了,这样对象还可能为空
                 */
                //volatile禁止重排序 所以给SINGTON2加上volatile
                //第一个线程可能没赋上值
                if(SINGTON2==null){
                    //写
                    SINGTON2=new SingleTon();
                }
                //synchronized 写 保证安全性   不保证有序性,所以结合
                        //volatile读 保证可见性 不保证原子性,从主内存对最新的
                //如果写操作是一个原子操作的话,能用volatile
                //不是的话,还要加上synchronized
                //只要不是操作系统上的原子性,要用volatile防止顺序变换
                return SINGTON2;
            }
        }
        return SINGTON2;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值