# Java Study **Repository Path**: oraclegao/java-study ## Basic Information - **Project Name**: Java Study - **Description**: java基础,数据结构,算法研究 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-12-24 - **Last Updated**: 2024-01-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 关键字:volatile - volatile是Java虚拟机提供的轻量级的同步机制 - volatile使用[内存屏障(Memory Barrier)指令](https://blog.csdn.net/CDC_hjl/article/details/122443822),保障可见性和禁止指令重排特性。 ## 特性 - 保证可见性 - 不保证原子性 - 禁止指令重排 ## 保证可见性 - 不可见:java线程之间通过主内存共享的变量,在线程工作内存中修改其值后,其它线程工作内存中的该变量值不发生变化。 - 使用volatile声明的变量,在线程工作内存中修改其值后,其它线程会收到修改的通知,也会修改其工作内存中的变量值。 - 可见性:java线程之间通过主内存共享的变量,在线程工作内存中修改其值后,其它线程工作内存中的该变量值也会变成该值。 - 代码详见:[VolatileVisibility.java](src/main/java/fun/pplm/study/volatileKW/VolatileVisibility.java) ## 不保证原子性 - 原子性:java编译后的一组指令,在多线程之间并行执行,要么全部执行完,要么全部不执行,而不会被其它线程从中间打断。 - 保证原子性方法:1.synchronized,2.使用JUC包下的Atomic系列类 - 代码详见:[VolatileAtomic.java](src/main/java/fun/pplm/study/volatileKW/VolatileAtomic.java) ## 禁止指令重排 - 线程中执行的java指令会被jvm保证依赖关系的前提下优化重排执行顺序 - 比如:对于单例模式创建对象:创建对象指令在赋值指令之前执行会导致创建多个对象实例 ## 应用场景 - 多个线程读,一个线程写的场景 - 结合synchronized,实现低开销的锁 ## volatile vs synchronized - 相同:都是解决线程之间的同步问题,volatile是值同步,synchronized是执行同步 - 作用:volatile解决的是变量(成员属性)在多线程间访问的可见性(值同步),而synchronized解决的是过程(方法)在多线程间执行的同步性 - 修饰域:volatile只能修饰变量;synchronized可以修饰方法和代码块 - 阻塞:多线程访问volatile修饰的变量不会发生阻塞;而多线程访问synchronized修饰的方法或代码块会阻塞 - 原子性:volatile保证数据可见性,但不保证原子性;而synchronized可以保证原子性,也可以间接保证可见性,因为会将工作内存和主内存中的数据做同步 - 性能:volatile是线程同步的轻量级实现,性能优于synchronized ## Refs - [Java基础:volatile详解](https://blog.csdn.net/xueping_wu/article/details/124541419) - [Java内存屏障](https://blog.csdn.net/CDC_hjl/article/details/122443822) - [并发番@Java内存模型&Volatile一文通(1.7版)](https://www.zybuluo.com/kiraSally/note/850631#5-synchronized-vs-volatile) # 锁 ## 可重入锁(ReentrantLock) - 可重入:是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁 - 实现可重入机制的锁就是可重入锁,包括:ReentrantLock, synchronized ## 公平锁 vs 非公平锁 - 公平锁:多线程按照申请锁的顺序来获取锁,不会出现争抢的情况. - 非公平锁:多线程不会按照顺序获取锁,会先尝试去争抢锁,有可能后申请的线程比先申请的线程先抢到锁,在高并发情况下,可能会造成优先级反转和饥饿的现象。 - synchronized是非公平锁。 - ReentrantLock两种模式均支持 ## CAS加锁的底层原理 - CAS: CompareAndSwap - CAS是硬件层面保证的CPU原子指令:执行期间会锁定总线,不会被操作系统调度挂起, - 加锁原理:cas指令指定一个内存位置,当内存值与预期原值一致,则将该内存位置更新为预期新值;cas(addr, 0, 1) 当内存地址是0的时候,会被update为1,表示加锁成功。