Java资源分享网 - 专业的Java学习网站 学Java,上Java资源分享网
【并发编程】volatile的原理我好像又懂了 PDF 下载
发布于:2024-05-09 09:27:08
(假如点击没反应,多刷新两次就OK!)

【并发编程】volatile的原理我好像又懂了 PDF 下载 图1

 

 

资料内容:

1、概述
在多线程编程中,确保线程安全和正确的执行顺序是非常重要的。由于多线程环境下,不同线程
之间共享内存资源,因此对这些资源的访问必须进行同步以避免出现竞态条件等问题。Java中提供了
多种方式来实现同步,其中 volatile 是一种非常轻量级的同步机制。
volatile 直译过来是不稳定的,意味着被其修饰的属性可能随时发生变化。该关键字为
Java提供了一个轻量级的同步机制:保证被volatile修饰的共享变量对所有线程总是可见的,也就
是当一个线程修改了一个被 volatile 修饰共享变量的值,新值总是可以被其他线程立即得知
相较于我们熟知的重量级锁 synchronized volatile 更轻量级,因为它不会引起上下文切
换和线程调度volatile 关键字的特性主要有以下几点:
1. 保证可见性:当一个变量被声明为 volatile 时,所有线程都可以看到它的最新值,
即每次读取都是从主内存中获取最新值,而不是从线程的本地缓存中获取旧值;
2. 保证有序性volatile 关键字可以禁止指令重排序。编译器和CPU为了提高代码执行
效率,可能会对指令进行重排序,这可能会导致线程安全问题。但是,当一个变量被声明
volatile 时,编译器和CPU会禁止对它进行指令重排序,保证指令执行的正确顺
序;
3. 无法保证原子性volatile 关键字并不能保证操作过程中的有序性,如果需要保证一
系列操作的原子性,仍然需要借助锁机制进行限制。
 
2、可见性保证
2.1、什么是可见性
可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他县城能够立即看
到修改的值。
 
2.2、例子举证
我们通过一个循环的例子进行举证,大致是使用一个变量标识一个 while 循环,通过新线程
修改这个标识,进而查看循环是否会结束。接下来将会对未加上和加上 volatile 进行举例查看
结果。
 
1. 未加 volatile 的普通flag
 
1 public class VolatileSeeTest {
2    static boolean flag = true;
3
4    public static void main(String[] args) throws
InterruptedException {
5        new Thread(() -> {
6            int i = 1;
7            while (flag) {
8                if (i == 1) {
9                    System.out.println("掉坑里了……");
10                    i = 0;
11               }
12           }
13            System.out.println("我出来啦!.(flag此时为" + flag);
14       }, "t1").start();
15
16        // 等待确保上面t1线程已经执行
17        Thread.sleep(1000L);
18
19        flag = false;
20        System.out.println("好小子,速速跳出坑来.(flag此时为" + flag);
21   }
22 }
23
24 ================================================
25    
26 此时结果打印:
27 掉坑里了……
28 好小子,速速跳出坑来.(flag此时为false)
29 (程序还未结束,代表t1线程还在死循环中)
30    
31 ================================================