Java并发中正确使用volatile
2023-09-11 14:16:12 时间
前几天并发编程群里有同学对volatile的用法提出了疑问,刚好我记得Twitter有关实时搜索的这个PPT对这个问题解释的很清晰并有一个实际的应用场景,于是周末把这个问题摘录了一些和并发相关的内容如下:
并发 – 定义 悲观锁 – Pressimistic locking 一个线性在执行一个操作时持有对一个资源的独占锁。(互斥) 一般用在冲突比较可能发生的场景下 乐观锁 – Optimistic locking 尝试采用原子操作,而不需要持有锁;冲突可被检测,如果发生冲突,具有相应的重试逻辑 通常用在冲突较少发生的场景下 非阻塞算法 – Non-blocking algorithm 算法确保对线程间竞争共享资源时候,不会因为互斥而使任一线程的执行无限延迟; 无锁算法 – Lock-free algorithm 如果系统整个流程的执行是无阻塞的(系统某一部分可能被短暂阻塞),这种非阻塞算法就是无锁的。 无锁算法比传统的基于锁的算法对系统的开销更小,且更容易在多核多CPU处理器上扩展; 在实时系统中可以避免锁带来的延迟; CAS (compare and swap)或LL/SC(load linked/store conditional),以及内存屏障相关的指令经常被用在算法实现中。 无等待算法 – Wait-free algorithm 如果每个线程的执行都是无阻塞的,这种非阻塞算法就是无等待的(比无锁算法更好) Java的并发 Java的内存模型并不保证一个线程可以一直以程序执行的顺序看到另一个线程对变量的修改,除非两个线程都跨越了同一个内存屏障。(Safe publication) Java内存模型 代码顺序规则 一个线程内的每个动作 happens-before 同一个线程内在代码顺序上在其后的所有动作 volatile变量规则 对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入 如果A happens-before B, B happens-before C,那 A happens-before C Safe publication案例class VolatileExample { int x = 0; volatile int b = 0; private void write() { x = 5; b = 1; private void read() { int dummy = b; while (x != 5) { public static void main(String[] args) throws Exception { final VolatileExample example = new VolatileExample(); Thread thread1 = new Thread(new Runnable() { public void run() { example.write(); Thread thread2 = new Thread(new Runnable() { public void run() { example.read(); thread1.start(); thread2.start(); thread1.join(); thread2.join();
x并不需要定义为volatile, 程序里可以有需要类似x的变量,我们只需要一个volatile变量b来确保线程a能看到线程1对x的修改:
根据代码顺序规则,线程1的x=5; happens-before b=1;; 线程2的int dummy = b; happens-before while(x!=5); 根据volatile变量规则,线程2的b=1; happens-before int dummy=b; 根据传递性,x=5; happens-before while(x!=5);java多线程关键字volatile、lock、synchronized volatile写和volatile读的内存语义: 1. 线程A写一个volatile变量,实质上是线程A向接下来将要读这个volatile变量的某个线程发出了(其对共享变量所在修改的)消息。 2. 线程B读一个volatile变量,实质上是线程B接收了之前某个线程发出的(在写这个volatile变量之前对共享变量所做修改的)消息。 3. 线程A写一个volatile变量,随后线程B读这个volatile变量,这个过程实质上是线程A通过主内存向线程B发送消息。
JUC系列(八)Java内存模型 volatile关键字与单例模式实践 JMM里有对于线程交换资源的一些约定 理解可以更好的参透JUC的内容 Volatile可以保证可见性和阻止操作系统的指令重排 理解多个不同的单例模式的实现方法
Java 中 volatile 用法 在 Java 并发编程中,volatile 是经常用到的一个关键字,它可以用于保证不同的线程共享一个变量时每次都能获取最新的值。volatile 具有锁的部分功能并且性能比锁更好,所以也被称为轻量级锁。下面具体分析 volatile 的用法及原理,涉及到内存模型、可见性、重排序以及伪共享等方面。
相关文章
- java虚拟机学习-Java常量池理解与总结(13-2)
- java并发中ExecutorService的使用
- 编程体系结构(05):Java多线程并发
- [Java 并发] Java并发编程实践 思维导图 - 第四章 对象的组合
- Java多线程之生产者消费者问题<一>:使用synchronized keyword解决生产者消费者问题
- C03-Java同步实践加强班第9周上机任务
- Java: mysql-connector-java
- “大话架构”阿里架构师分享的Java程序员需要突破的技术要点
- 一文详解 Java 并发模型
- Java高并发编程基础三大利器 - CountDownLatch
- Java并发编程 LockSupport源码分析
- 【Java】Eclipse如何创建java项目并运行
- maven项目的java和resources等文件夹不在Java Resources的文件夹里,并且缺少Deployment...
- Java序列化的几种方式以及序列化的作用
- 《Java线程与并发编程实践》—— 1.3 练习
- 《Java EE 7精粹》—— 第2章 Servlets 2.1 WebServlet
- Java 并发工具包 java.util.concurrent 大全
- 2022.18 Java 类加载回顾总结
- Java并发思考
- java面试
- SSM实战项目——Java高并发秒杀API
- java.lang.OutOfMemoryError: Java heap space
- Java 开发, volatile 你必须了解一下
- 正确使用MySQL JDBC setFetchSize()方法解决JDBC处理大结果集 java.lang.OutOfMemoryError: Java heap space
- java中获取比毫秒更为精确的时间
- Java_并发工具包 java.util.concurrent 用户指南(转)
- 『Java练习生的自我修养』java-se进阶² • 并发与多线程
- Java打印车票主要学习Java的比较语句
- Java并发编程(二)同步
- Java并发编程--总结
- Java操作Mongodb 保存/读取java对象到/从mongodb
- Java多线程-初识并发问题