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: 1,772 · Posted: 2021-09-28
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...