深入浅出Java并发多线程(18) -并发编程底层原理(3)

1 原子性

在这里插入图片描述

1.1 java 中的原子操作

在这里插入图片描述

1.2 longdouble 的原子性

在这里插入图片描述

在这里插入图片描述

1.3 原子操作 + 原子操作 !=原子操作

在这里插入图片描述

2 面试常见问题

2.1 单例模式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1.1 饿汉式,静态常量,可用

  • 在类装载的时候就完成了实例化,避免了线程同步问题,因为类的加载是由JVM自身保证线程安全的。后续其他类想要调用,永远拿到的都是这个实例。
/**
 * @Description 饿汉式,静态常量,可用
 * @Author tzb
 * @Date 2021/4/11 16:08
 * @Version 1.0
 **/
public class Singleton1 {

    private final static Singleton1 INSTANCE  = new Singleton1();

    private Singleton1(){

    }

    public static Singleton1 getInstance(){
        return INSTANCE;
    }

}


2.1.2 饿汉式,静态代码块,可用

/**
 * @Description 饿汉式,静态代码块,可用
 * @Author tzb
 * @Date 2021/4/11 16:08
 * @Version 1.0
 **/
public class Singleton2 {

    private final static Singleton2 INSTANCE;

    static {
        INSTANCE = new Singleton2();
    }

    private Singleton2(){
    }

    public static Singleton2 getInstance(){
        return INSTANCE;
    }

}

2.1.3 懒汉式,线程不安全,不可用

  • 如果2个线程同时到达19行,由于instance没有被执行过,两个线程都会执行20行。多次创建了实例。

在这里插入图片描述

/**
 * @Description 懒汉式
 * @Author tzb
 * @Date 2021/4/11 16:17
 * @Version 1.0
 **/
public class Singleton3 {

    private static Singleton3 instance;

    private Singleton3(){

    }

    public static Singleton3 getInstance(){
        if(null == instance){
            instance = new Singleton3();
        }
        return instance;
    }

}

2.1.4 懒汉式,线程安全,同步方法,不推荐用

  • 效率太低
/**
 * @Description 懒汉式,线程安全,不推荐
 * @Author tzb
 * @Date 2021/4/11 16:17
 * @Version 1.0
 **/
public class Singleton4 {

    private static Singleton4 instance;

    private Singleton4(){

    }

    public synchronized static Singleton4 getInstance(){
        if(null == instance){
            instance = new Singleton4();
        }
        return instance;
    }

}

2.1.5 懒汉式,线程不安全,同步代码块,不可用

  • 2个线程都进入了20行,线程1先执行21,释放锁。线程2后执行21

在这里插入图片描述

public class Singleton5 {

    private static Singleton5 instance;

    private Singleton5(){

    }

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

}

2.1.6 双重检测 【推荐,面试用】

在这里插入图片描述

  • 不加 volatile,假设进行了重排序,执行了1,2条,左边的rs不为空,但是没有内涵(构造函数没有执行完,里面的属性没有完成赋值)。此时对第2个线程进来,发现rs不为空(但是rs内部没有准备完毕),第2个线程会跳过新建的过程,直接返回,会导致NPE。
  • 不加 volatile,也存在可见性的问题,线程1初始化完了rs,线程2看不到,
    在这里插入图片描述
/**
 * @Description 双重检查
 * @Author tzb
 * @Date 2021/4/11 16:17
 * @Version 1.0
 **/
public class Singleton6 {

    private volatile static Singleton6 instance;

    private Singleton6() {

    }

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

2.1.7 静态内部类,推荐用

  • 属于懒汉式
/**
 * @Description 静态内部类
 * @Author tzb
 * @Date 2021/4/11 16:17
 * @Version 1.0
 **/
public class Singleton7 {

    private Singleton7() {

    }
    public static Singleton7 getInstance() {
        return SingletonInstance.INSTANCE;
    }

    private static class SingletonInstance {
        private static final Singleton7 INSTANCE = new Singleton7();
    }
}

2.1.8 枚举【推荐用】

/**
 * @Description 枚举单例
 * @Author tzb
 * @Date 2021/4/11 16:17
 * @Version 1.0
 **/
public enum Singleton8 {
    INSTANCE;

    public void whatever() {
        
    }

}

2.2 不同写法的对比

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值