线程安全原理简析及HashMap多线程并发5种场景异常分析(1)

简介: 线程安全原理简析及HashMap多线程并发5种场景异常分析(1)

多线程并发出现异常的情况


单例模式


public class DoubleCheckSingleton {
    /**
     * 使用volatile,在多线程场景下,确保在判断null时,对所有线程可见
     */
    private static volatile DoubleCheckSingleton uniqInstance;
    /**
     * 构造器私有,防止外部实例化该类
     */
    private DoubleCheckSingleton() {}
    /**
     * 静态方法实例化,由于在类内部,可以调用构造器
     */
    public static DoubleCheckSingleton getInstance(){
        if (null == uniqInstance) { // 此处判断需要可见性volatile
            synchronized (DoubleCheckSingleton.class) {
                if (null == uniqInstance) {
                    //延迟初始化
                    uniqInstance = new DoubleCheckSingleton();
                }
            }
        }
        return uniqInstance;
    }
}


可见性


  • 引发原因


CPU高速缓存 由于各个线程会在执行是从 主存 加载到CPU高速缓存中执行,节省读取内存时间(CPU速度>> 主存速度)


image.png


线程A对共享变量V做了修改,其它线程B看到V的值还是之前的old失效数据


  • 后果(以单例模式举例)


失效数据


线程A已经创建了instance,但是线程B读取的instance还是null,会导致创建了两个instance,A和B拿到的实例不一样!!


失效值可能导致错误的结果或者导致活跃性问题。


  • fix方案


volatile


加锁(syn、lock)


有序性


  • 引发原因


编译优化之指令重排序


CPU执行指令时会有一些指令重排序以期最大效率


image.png


  • 后果(以单例模式举例)



单例模式赋值和实例化的重排序导致的异常


image.png


  • fix方案


volatile


加锁


通过Happens-before规则实现


内置锁的释放锁操作发生在该锁随后的加锁操作之前


一个volatile变量的写操作发生在这个volatile变量随后的读操作之前


原子性


  • 引发原因


线程切换


CPU调度是时间片轮转如下图


image.png


public方法如有对共享变量读取-修改-写入等类型有依赖的操作序列时,需要是原子性完成

自增、先检查后执行

相关文章
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
559 0
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
582 83
|
存储 Java 调度
Java虚拟线程:轻量级并发的革命性突破
Java虚拟线程:轻量级并发的革命性突破
623 83
|
12月前
|
设计模式 缓存 安全
【JUC】(6)带你了解共享模型之 享元和不可变 模型并初步带你了解并发工具 线程池Pool,文章内还有饥饿问题、设计模式之工作线程的解决于实现
JUC专栏第六篇,本文带你了解两个共享模型:享元和不可变 模型,并初步带你了解并发工具 线程池Pool,文章中还有解决饥饿问题、设计模式之工作线程的实现
740 2
|
12月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
600 1
|
12月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
524 1
|
Java API 微服务
为什么虚拟线程将改变Java并发编程?
为什么虚拟线程将改变Java并发编程?
589 83
|
12月前
|
Java
如何在Java中进行多线程编程
Java多线程编程常用方式包括:继承Thread类、实现Runnable接口、Callable接口(可返回结果)及使用线程池。推荐线程池以提升性能,避免频繁创建线程。结合同步与通信机制,可有效管理并发任务。
403 6
|
机器学习/深度学习 消息中间件 存储
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
511 0
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
698 16