【多线程:volatile】原理

简介: 【多线程:volatile】原理

【多线程:volatile】原理

01.介绍

volatile的底层实现原理是内存屏障

1.对volatile变量的写指令后会加入写屏障
2.对volatile变量的读指令前会加入读屏障

02.volatile保证可见性原理

写屏障:保证在该屏障之前的,对共享变量的改动都同步到主存当中。

    public void actor2(I_Result r){
        num = 2;
        ready = true; // ready是volatile修饰的,且ready是写操作
        // ready后有写屏障
    }

读屏障:保证在该屏障之后,对共享变量的读取,加载的是主存中的最新数据

    public void actor1(I_Result r){
        // 因为ready是读操作
        // 在ready之前有读屏障
        if(ready){
            r.r1 = num + num;
        }else{
            r.r1 = 1;
        }
    }

解释

写屏障可以保证自己和自己之前的共享变量 都同步到主存中,就像这里的num = 2是在ready = true之前,那么共享变量ready与num都会同步到主存当中
读屏障则是可以保证自己和自己之后的共享变量读取都是最新的,例如这里if(ready)就读取了ready 还有 r.r1 = num + num,这里读取了num
总结:通过读写屏障保证了 加了volatile的变量不论是写还是对都是最新的数据,且 对于写之前 读之后的数据也都是最新数据。这就是可见性实现的原理。

03.volatile保证有序性原理

写屏障:确保指令重排序时,不会将写屏障之前的代码排在写屏障之后。

    public void actor2(I_Result r){
        num = 2;
        ready = true; // ready是volatile修饰的,且ready是写操作
        // ready后有写屏障
    }

读屏障:确保指令重排序时,不会将读屏障之后的代码排在读屏障之前。

    public void actor1(I_Result r){
        // 因为ready是读操作
        // 在ready之前有读屏障
        if(ready){
            r.r1 = num + num;
        }else{
            r.r1 = 1;
        }
    }

解释

写屏障确保指令重排序时,不会将写屏障之前的代码排在写屏障之后,例如这个例子中的ready = true是读操作,保证了ready之前的代码不会出现在ready之后
读屏障则是确保指令重排序时,不会将读屏障之后的代码排在写屏障之前,例如这个例子中的if(ready)保证了ready之后的代码不会出现在ready之前,不过这里ready不存在这个问题 因为这里只有ready为true时才能进入
总结:通过读写屏障保证了 加了volatile的变量写之前的代码不会出现在写屏障之后 这就保证了 这个变量的位置固定,同时读屏障保证了读屏障之后的代码不会出现在读屏障之前 也保证了位置固定,所以在写这个变量时 这个变量不会出现指令重排序,读这个变量时 这个变量也不会出现指令重排序,保证了有序性。

目录
相关文章
|
3月前
|
安全 Java 数据库
一天十道Java面试题----第四天(线程池复用的原理------>spring事务的实现方式原理以及隔离级别)
这篇文章是关于Java面试题的笔记,涵盖了线程池复用原理、Spring框架基础、AOP和IOC概念、Bean生命周期和作用域、单例Bean的线程安全性、Spring中使用的设计模式、以及Spring事务的实现方式和隔离级别等知识点。
|
3月前
|
编解码 网络协议 API
Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
|
3月前
|
存储 SQL 缓存
揭秘Java并发核心:深度剖析Java内存模型(JMM)与Volatile关键字的魔法底层,让你的多线程应用无懈可击
【8月更文挑战第4天】Java内存模型(JMM)是Java并发的核心,定义了多线程环境中变量的访问规则,确保原子性、可见性和有序性。JMM区分了主内存与工作内存,以提高性能但可能引入可见性问题。Volatile关键字确保变量的可见性和有序性,其作用于读写操作中插入内存屏障,避免缓存一致性问题。例如,在DCL单例模式中使用Volatile确保实例化过程的可见性。Volatile依赖内存屏障和缓存一致性协议,但不保证原子性,需与其他同步机制配合使用以构建安全的并发程序。
70 0
|
2月前
|
存储 缓存 Java
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
137 29
什么是线程池?从底层源码入手,深度解析线程池的工作原理
|
1月前
|
Java 编译器 程序员
【多线程】synchronized原理
【多线程】synchronized原理
59 0
|
1月前
|
Java 应用服务中间件 API
nginx线程池原理
nginx线程池原理
32 0
|
2月前
|
存储 缓存 Java
JAVA并发编程系列(11)线程池底层原理架构剖析
本文详细解析了Java线程池的核心参数及其意义,包括核心线程数量(corePoolSize)、最大线程数量(maximumPoolSize)、线程空闲时间(keepAliveTime)、任务存储队列(workQueue)、线程工厂(threadFactory)及拒绝策略(handler)。此外,还介绍了四种常见的线程池:可缓存线程池(newCachedThreadPool)、定时调度线程池(newScheduledThreadPool)、单线程池(newSingleThreadExecutor)及固定长度线程池(newFixedThreadPool)。
|
3月前
|
存储 NoSQL Java
线程池的原理与C语言实现
【8月更文挑战第22天】线程池是一种多线程处理框架,通过复用预创建的线程来高效地处理大量短暂或临时任务,提升程序性能。它主要包括三部分:线程管理器、工作队列和线程。线程管理器负责创建与管理线程;工作队列存储待处理任务;线程则执行任务。当提交新任务时,线程管理器将其加入队列,并由空闲线程处理。使用线程池能减少线程创建与销毁的开销,提高响应速度,并能有效控制并发线程数量,避免资源竞争。这里还提供了一个简单的 C 语言实现示例。
|
3月前
|
存储 Java
线程池的底层工作原理是什么?
【8月更文挑战第8天】线程池的底层工作原理是什么?
116 8
|
2月前
|
安全 Java API
Java线程池原理与锁机制分析
综上所述,Java线程池和锁机制是并发编程中极其重要的两个部分。线程池主要用于管理线程的生命周期和执行并发任务,而锁机制则用于保障线程安全和防止数据的并发错误。它们深入地结合在一起,成为Java高效并发编程实践中的关键要素。
31 0

热门文章

最新文章