Java并发编程之volatile关键字

从事Java编程的程序员若想有所成长,就肯定绕不过并发编程,今天就聊一聊在Java并发编程中volatile关键字。

以下是本文的目录大纲:

一. 并发编程中的三个概念

二. 为什么没有退出循环

三. 进一步认识volatile关键字

四. volatile关键字的使用场景

五. 一道面试题

一. 并发编程中的三个概念

在并发编程中,我们通常需要考虑三个问题:原子性问题,可见性问题,有序性问题。我们先看具体看一下这三个概念:

原子性

原子性是指一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。

比如我们去12306上面买高铁票,进入买票的页面时,通常有选择乘车人--->选择座位--->付款--->出票这四个步骤,这些步骤在执行过程中就需要保存原子性。不能说我付了钱,但是当应该给我票时程序却暂停了,不在继续执行了。如果是这样,那恐怕就不会有人用12306了

public void buyingTickets(){
    // 选择乘车人
    selectPassengers();
    // 选择座位
    selectSeat();
    // 付款
    payment();
    // 出票
    getTickets();
}

 

可见性

可见性是指当多个线程访问同一个全局变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

还是以12306上买票为例,打开12306买票时,我们都会看到剩余票数,这个剩余票数在程序实现中就是一个多线程共享的全局变量,这里我把起名为remainingTickets。那这个remainingTickets的取值在多个线程中是可见的,当线程1修改了remainingTickets的值时,线程2看到的remainingTickets的值应该是线程1修改过后的值。比如当前剩余票数remainingTickets=10;有A和B同时通过12306来购买同一班高铁票(始发地和目的地相同)。假如A先购买完成,那B购买时,看到的剩余票数remainingTickets=9。否则如果一个人买到票后,另一个看到票数却未做相应的扣减,那节假日再也不怕买不到票了,高铁恐怕也要经常超载了。

有序性

有序性指的是指令重排序,在Java内存模型中,在不影响单线程情况下程序执行结果的前提下,允许编译器和处理器对指令进行重排序,从而提高执行效率。

这种重排序可以分为两种情况来判断,但是这两种情况归根结底都是最后执行的汇编指令的重排序。

第一种情况是我有多行代码,编译器对多行代码的执行指令进行了重排序,比如:

int i = 0;      
boolean flag = false;
i = 1;        //语句1 
flag = true;  //语句2

上面代码定义了一个int型变量,定义了一个boolean类型变量,然后分别对两个变量进行赋值操作。从代码顺序上看,语句1是在语句2前面的,那么JVM在真 正执行这段代码的时候并不一定保证语句1一定会在语句2前面执行,有可能会因为指令重排序导致语句2在语句1前面执行。这里无论是语句1先执行还是语句2先执行都不影响程序的执行结果。

第二种情况就是我就一行代码,但是这一行代码涉及多条执行指令。比如构造

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值