温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java中happens-before的原则

发布时间:2021-09-17 09:37:03 来源:亿速云 阅读:123 作者:chen 栏目:大数据

本篇内容介绍了“Java中happens-before的原则”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

在Java中有一个很重要的原则,这个原则是判断线程是否存在数据竞争、线程是否安全的主要依据,这个原则就是happens-before原则。我们首先看一下到底什么是happens-before原则。简单来说happens-before原则就是JMM中定义的两项操作之间的偏向关系。假如我们有两个操作A和B。如果A操作先行发生于B操作,也就是A操作在B操作之前发生,那么在A操作在发生之后产生的影响B操作可以获取到,这里所说的影响主要包括修改共享变量、调用方法等。上述就是happens-before原则的定义,下面我们用一个简单的例子来说明一下happens-before原则到底有什么作用。

Java中happens-before的原则

我们假设上述代码中的3条语句分别由3个线程执行,并假如这3个线程分别是thread-1、thread-2、thread-3。如果我们指定thread-1要优先于thread-2执行那么我们就会得出结论thread-2在执行完成后,变量j的值一定是1。原因就是根据happens-before原则,thread-1先行发生于thread-2,所以thread-1执行后的值,thread-2是可以获取到的,并且我们假设thread-3没有执行。那么在thread-1执行后,变量i的值没有被其它线程修改过,所以thread-2在获取变量i时值为1。下面我们假设thread-1和thread-2还具有happens-before关系,也就是说thread-1在thread-2之前执行并且我们假设thread-2和thread-3并没有happens-before关系。也就是说thread-2和thread-3谁先执行并不是确定的。如果thread-3在thread-2之前执行的,那么thread-2中变量j的值是多少呢?答案可想而知,变量j的值是不确定的。因为我们并不确定thread-1和thread-3到底谁先执行。如果thread-3比thread-1先执行,那么因为thread-1和thread-2有happens-before关系,所以并不会对变量j的值产生影响,但如果thread-1比thread-3先执行,那么thread-2在获取变量i的值时,就是有可能获取到过期的数据了,这就造成的所谓的线程安全问题了。

在JMM中直接就具有happens-before原则,我们不需要进行任何同步,可以直接在编码中使用它们。如果代码中的操作没有happens-before原则的话,那么虚拟机在执行的时候,就有可能对它们进行随意的重排序。下面我们看一下在JMM中都有哪些操作是默认具有happens-before原则的。

  • 程序次序规则:在一个线程内,按照程序代码顺序,写在前面的代码先行发生于写在后面的代码。(暂时不考虑分支判断、循环等)

  • 管程锁定规则:一个unlock操作先行发生于后面对同一个锁的lock操作。

  • volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作。

  • 线程启动规则:Thread对象的start()方法先行发生于此线程的每一个动作。

  • 线程终止规则:线程中的所有操作都先行发生于对此线程的终止检测。

  • 对象终结规则:一个对象的初始化先行发生于它的finalize()方法。

  • 传递性:如果操作A先行发生于操作B,操作B先行发生于操作C,那操作也A先行发生于操作C。

“Java中happens-before的原则”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI