深入理解Happens-Before原则:以实例解析并发编程的基石

本文详细解释了Happens-Before原则在Java内存模型中的作用,通过实例展示了单线程、锁的释放与获取、volatile变量以及线程启动与终止等情况下的规则应用,强调了遵循这一原则对编写正确并发程序的重要性。
摘要由CSDN通过智能技术生成

在最近的一次面试中面试官问到了Happens-Before原则,作此篇回顾下知识点。

在并发编程中,为了保证程序的正确性和可预测性,我们需要理解并遵循一系列内存访问规则。Happens-Before原则定义了线程间可见性和顺序性的保证。所有此篇文章将通过实例详细介绍Happens-Before原则。

在这里插入图片描述

Happens-Before原则概述

Happens-Before原则是Java内存模型(JMM)中定义的一种偏序关系,用于确定两个操作之间的相对顺序。

如果操作A happens-before 操作B,那么操作A的结果对操作B是可见的,且操作A的执行顺序在操作B之前。这就意味着,当线程B读取到线程A写入的值时,可以确保线程A的写入操作已经发生。

Happens-Before原则的实例解析

单一线程内的操作

在一个线程内,按照程序顺序执行的操作自然满足Happens-Before原则。这是因为单个线程内的操作是顺序执行的,没有并发访问的问题。

举个栗子:

	int a = 1; // 操作A  

	int b = a; // 操作B

在这个例子中,操作A(给变量a赋值为1)happens-before操作B(读取变量a的值并赋给变量b)。所以,操作B读取到的b的值一定是1。

锁的释放与获取

当一个线程释放锁时,它之前对共享变量的修改对其他线程是可见的;当一个线程获取锁时,它可以读取到之前释放锁线程对共享变量的修改。这里,锁的释放操作happens-before锁的获取操作。

举个栗子:

	Object lock = new Object();  

	int sharedVariable = 0;  

	  

	// 线程A  

	synchronized(lock) {  

	    sharedVariable = 1; // 操作A  

	} // 释放锁  

	  

	// 线程B  

	synchronized(lock) {  

	    int temp = sharedVariable; // 操作B  

	} // 获取锁

对于上面的栗子,线程A在释放锁之前将sharedVariable赋值为1(操作A)。由于锁的释放操作happens-before锁的获取操作,线程B在获取锁后读取到的sharedVariable的值一定是1。

volatile变量的写与读

对volatile变量的写操作happens-before后续对该变量的读操作。这就意味着,当一个线程写入一个volatile变量时,其他线程可以立即看到这个修改。

举个栗子:

	volatile boolean flag = false;  

	  

	// 线程A  

	flag = true; // 操作A  

	  

	// 线程B  

	if (flag) { // 操作B  

	    // ...  

	}

上面的代码中,线程A将volatile变量flag设置为true(操作A)。因为volatile变量的写操作happens-before读操作,线程B在读取flag时,一定能够看到其值为true

线程启动与终止

线程的启动(start)操作happens-before此线程内的任意操作。线程的所有操作都happens-before其他线程检测到该线程已经终止(通过Thread.join()方法或Thread.isAlive()的返回值等方法)。

举个例子:

	Thread thread = new Thread(() -> {  

	    // 线程内操作  

	    System.out.println("xiaowei haoshuai!");  

	});  

	thread.start(); // 操作A  

	thread.join(); // 操作B

上面的代码中,线程启动操作(操作A)happens-before线程内的打印操作,而线程内的打印操作又happens-before线程终止检测操作(操作B)。因此,主线程在调用thread.join()方法时,可以确保子线程已经执行了打印操作。

Happens-Before原则小结

Happens-Before原则是并发编程中的基石,它定义了线程间操作顺序和可见性的保证。

我们理解并遵循这一原则,就可以编写出正确且可预测的并发程序。本篇文章到此结束,希望我们开发者们在编写代码时都牢记住这一原则哦!

在这里插入图片描述

  • 26
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小威要向诸佬学习呀

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值