Java 并发编程之 happens-before 7 条规则
Java juc About 3,121 words定义
规定了对共享变量的写操作对其他线程的读操作可见。
它是可见性与有序性的一套规则总结。
synchronized
假设t1先执行:t1线程解锁m前对x变量的写,对于对m加锁的t2线程,x变量的读可见。
输出:10
public class SyncDemo {
static int x;
static final Object m = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (m) {
x = 10;
}
}, "t1").start();
new Thread(() -> {
synchronized (m) {
System.out.println(x);
}
}, "t2").start();
}
}
volatile
假设t1先执行:t1线程对volatile变量x的写,对于t2线程对变量x的读可见。
输出:10
public class VolatileDemo {
volatile static int x;
public static void main(String[] args) {
new Thread(() -> {
x = 10;
}, "t1").start();
new Thread(() -> {
System.out.println(x);
}, "t2").start();
}
}
线程 start 前
线程start前对变量x的写,当该线程启动后,在该线程中对变量x的读可见。
public class BeforeThreadStartDemo {
static int x;
public static void main(String[] args) {
x = 10;
new Thread(() -> {
System.out.println(x);
}, "t1").start();
}
}
线程结束后
t1线程结束前对变量的写,当其他线程得知t1线程结束运行后的读可见。
public class AfterThreadExecuteDemo {
static int x;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
x = 10;
}, "t1");
t1.start();
t1.join();
System.out.println(x);
}
}
线程 interrupt
线程t1打断线程t2前对变量x的写,对于其他线程得知t2被打断后对变量x的读可见(示例中的其他线程指的是是main线程和t2线程)。
public class ThreadInterruptDemo {
static int x;
public static void main(String[] args) {
Thread t2 = new Thread(() -> {
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("t2#" + x);
break;
}
}
}, "t2");
t2.start();
new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
x = 10;
t2.interrupt();
}, "t1").start();
while (!t2.isInterrupted()) {
Thread.yield();
}
System.out.println("main#"+ x);
}
}
默认值
对于默认值的写(0,false,null),对其他线程对该变量的读可见。
public class DefaultValueDemo {
static int x = 10;
static boolean y = true;
static Object z = new Object();
public static void main(String[] args) {
new Thread(() -> {
System.out.println(x);
System.out.println(y);
System.out.println(z);
}, "t1").start();
}
}
传递性
如果x hb -> y,并且y hb -> z,那么有x hb -> z,配合volatile的防止指令重排。
// HB: HappenBefore
public class HBDemo {
volatile static int x;
static int y;
public static void main(String[] args) {
new Thread(() -> {
y = 20;
x = 10;
}, "t1").start();
new Thread(() -> {
System.out.println("y#" + y);
System.out.println("x#" + x);
}, "t2").start();
}
}
Views: 2,374 · Posted: 2021-09-28
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...