定义
Happens-before 关系是用来描述和可见性相关问题的,我们可以简单理解,就是按顺序执行,一个个来。
举例:小情侣一起做饭,小美女在洗米,小帅哥在弄电饭锅,
必须等米洗完后,才能开始煮饭。
在java中,happens-before是一种关系运算符,用于定义两个事件之间的时间顺序,happens-before只在 Java 的内存模型中起作用。保证了可见性。
如果第一个操作happens-before第二个操作(也可以描述为第一个操作和第二个操作之间的happens-before关系),那么我们说第一个操作对于第二个操作是一定可见的,当执行第二个操作时,保证看到第一个操作的结果。
Java中的happens-before关系可以通过使用synchronized关键字来实现。synchronized关键字可以将多个方法或代码块设置为同步的,即只有一个线程可以访问它们,而其他线程则需要等待。
下面是一个示例代码,展示了如何使用synchronized关键字实现happens-before关系:
public class MyConcurrency {
private static final Object lock = new Object();
public void method1() {
synchronized (lock) {
System.out.println("Method1 is executing");
}
}
public void method2() {
synchronized (lock) {
System.out.println("Method2 is executing");
}
}
public void method3() {
synchronized (lock) {
System.out.println("Method3 is executing");
}
}
}
在上面的示例代码中,我们创建了一个名为lock的对象作为同步锁,然后在每个方法中使用synchronized关键字将其包围。这意味着只有一个线程可以访问method1()、method2()和method3()方法,而其他线程则需要等待。
Happens-before 关系的规则
(1)单线程规则:在单线程中,按照程序代码的先后顺序,先执行的操作在后执行的操作之前
(2)锁操作规则(Lock和synchronized接口等):如果操作A是解锁,操作B是锁同一个锁,那么hb(A,B)。
(3) volatile 变量规则:对volatile 变量的写操作happens-before 之后是对该变量的读操作。
举一个不具备 happens-before 关系的例子
比如多个线程同时对一个数进行操作,如下
public class Visibility {
int x = 0;
public void write() {
x = 1;
}
public void read() {
int y = x;
}
}