并发编程三特性-有序性性技术保障

3.1.有序性定义

有序性:即程序执行的顺序按照代码的先后顺序执行。

有前面的文章可知,JVM存在指令重排,所以存在有序性问题。

在Java中,由于happens-before原则,单线程内的代码是有序的,可以看做是串行(as-if-serial)执行的。但是在多线程环境下,多个线程的代码是交替的串行执行的,这就产生了有序性问题。

3.2.Java自带的有序性

在前面的文章可知,Java提供了happens-before原则保证程序基本的有序性,主要规则如下:

  • 线程内部规则:在同一个线程内,前面操作的执行结果对后面的操作是可见的。
  • 同步规则:如果一个操作x与另一个操作y在同步代码块/方法中,那么操作x的执行结果对操作y可见。
  • 传递规则:如果操作x的执行结果对操作y可见,操作y的执行结果对操作z可见,则操作x的执行结果对操作z可见。
  • 对象锁规则:如果线程1解锁了对象锁a,接着线程2锁定了a,那么,线程1解锁a之前的写操作的执行结果都对线程2可见。
  • volatile变量规则:如果线程1写入了volatile变量v,接着线程2读取了v,那么,线程1写入v及之前的写操作的执行结果都对线程2可见。
  • 线程start原则:如果线程t在start()之前进行了一系列操作,接着进行了start()操作,那么线程t在start()之前的所有操作的执行结果对start()之后的所有操作都是可见的。
  • 线程join规则:线程t1写入的所有变量,在任意其它线程t2调用t1.join()成功返回后,都对t2可见。

而有序性问题,都是发生在happens-before原则之外的状况。

3.3.有序性问题示例

前置说明,其实网上有很多关于有序性的实例,类似如下:

 

通过运行结果发现,多线程环境中,代码是交替的串行执行的,这样会导致产生意料之外的结果。

3.4.有序性保障技术

在Java中提供了多种有序性保障措施,这里主要涉及两种:

  • 通过synchronized关键字定义同步代码块或者同步方法保障可见性。
  • 通过Lock接口保障可见性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值