【JavaSE】【多线程】volatile,wait/notify


一、volatile关键字

volatile可以保证内存可见性,只能修饰变量。

1.1 内存可见性

在前面介绍线程不安全原因时介绍到了,在Java中有JMM (Java Memory Model)(Java内存模型)来介绍。

计算机运行代码/程序的时候,访问数据常常要从内存中访问(定义变量时变量就储存在内存中),
然而CPU从内存中读取数据相比于从寄存器中读取数据要慢上很多(几千上万倍),CPU在进行读/写内存的时候速度就会降低。

为了解决这种问题,提高效率,编译器就可能会对代码优化,把一些本来要读取内存的操作,优化为读取寄存器,减少读取内存的次数。这就会导致内存可见性问题。

例如以下代码输入一个不为0的数,本应该打印“threade1结束”,但是并没有。

import java.util.Scanner;
public class Demo {
   
    public static int isQuite = 0;
    public static void main(String[] args) {
   
        Thread thread1 = new Thread(() -> {
   
           while(isQuite == 0) {
   
               
           }
            System.out.println("threade1结束");
        }) ;
        Thread thread2 = new Thread(() -> {
   
            Scanner scanner = new Scanner(System.in);
            isQuite = scanner.nextInt();
        });
        thread1.start();
        thread2.start();
    }
}

以上述代码讲解:
在thread1中while先读取isQuite的值,在进行比较,然而编译器/JVM发现多次得到的isQuite都是0,这个线程也没有修改isQuite操作,然后编译器/JVM就大胆优化只进行第一次的读取isQuite操作,后续直接从寄存器里面读取。

其实编译器/JVM进行优化是不可控的,如果在while循环里面加上sleep,sleep的时间够久了,已经够进行读取操作,可能就不会优化了。

1.2 volatile解决内存可见性问题

如上诉代码,我们直接在isQuite加上volatile修饰,就告诉编译器/JVM不要进行优化,就可以解决问题。

volatile可以解决内存可见性问题,解决不了原子性问题。

import java.util.Scanner;
public class Demo {
   
	volatile public static int isQuite = 0;
    public static void main(String[] args) {
   
        Thread thread1 = new Thread(() -> {
   
           while(isQuite == 0) {
   
               
           }
            System.out.println("threade1结束");
        
评论 145
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸽鸽程序猿

蟹蟹大哥

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值