【多线程:happen-before】

简介: 【多线程:happen-before】

【多线程:happen-before】

01.介绍

happens-before 规定了对共享变量的写操作对其它线程的读操作可见,它是可见性与有序性的一套规则总结,抛开happens-before 规则,JMM并不能保证一个线程对共享变量的写,对于其它线程对该共享变量的读是可见的。

02.happens-before规则

规则一

线程解锁 m 之前对变量的写,对于接下来对 m 加锁的其它线程对该变量的读可见

    static int x;
    static Object m = new Object();
    new Thread(()->{
        synchronized(m) {
        x = 10;
        }
    },"t1").start();
    
    new Thread(()->{
        synchronized(m) {
        System.out.println(x);
        }
    },"t2").start();

规则二

线程对 volatile 变量的写,对接下来其它线程对该变量的读可见

    volatile static int x;
    new Thread(()->{
        x = 10;
    },"t1").start();
    
    new Thread(()->{
        System.out.println(x);
    },"t2").start();

规则三

线程 start 前对变量的写,对该线程开始后对该变量的读可见

    static int x;
    x = 10;
    
    new Thread(()->{
        System.out.println(x);
    },"t2").start();

规则四

线程结束前对变量的写,对其它线程得知它结束后的读可见(比如其它线程调用 t1.isAlive() 或 t1.join()等待 它结束)

    static int x;
    Thread t1 = new Thread(()->{
        x = 10;
    },"t1");
    
    t1.start();
    t1.join();
    System.out.println(x);

规则五

线程 t1 打断 t2(interrupt)前对变量的写,对于其他线程得知 t2 被打断后对变量的读可见(通过 t2.interrupted 或 t2.isInterrupted)

    static int x;
    public static void main(String[] args) {
        Thread t2 = new Thread(()->{
            while(true) {
                if(Thread.currentThread().isInterrupted()) {
                    System.out.println(x);
                    break;
                }
            }
        },"t2");
    
        t2.start();
        new Thread(()->{
            sleep(1);
            x = 10;
            t2.interrupt();
        },"t1").start();
    
        while(!t2.isInterrupted()) {
            Thread.yield();
        }
        System.out.println(x);
    }

规则六

对变量默认值(0,false,null)的写,对其它线程对该变量的读可见

规则七

具有传递性,如果 x hb-> y 并且 y hb-> z 那么有 x hb-> z ,配合 volatile 的防指令重排,有下面的例子

    volatile static int x;
    static int y;
    new Thread(()->{ 
        y = 10;
        x = 20;
    },"t1").start();
    
    new Thread(()->{
        // x=20 对 t2 可见, 同时 y=10 也对 t2 可见
        System.out.println(x); 
    },"t2").start();
目录
相关文章
|
6月前
|
Java 调度
【多线程和高并发】一:线程实现和synchronize
【多线程和高并发】一:线程实现和synchronize
|
6月前
|
调度
多线程和异步编程:介绍 Operation 和 OperationQueue。
多线程和异步编程:介绍 Operation 和 OperationQueue。
51 0
|
6月前
condition_variable与多线程,互斥锁
condition_variable与多线程,互斥锁
37 0
|
监控
【多线程:interrupt 方法详解】
【多线程:interrupt 方法详解】
158 0
|
设计模式 数据挖掘 C++
C++并发与多线程(三)单例设计模式与共享数据分析、call_once、condition_variable使用
C++并发与多线程(三)单例设计模式与共享数据分析、call_once、condition_variable使用
133 0
|
存储 缓存 Java
高并发之volatile、synchronized关键和内存屏障(Memory Barrier)
高并发之volatile、synchronized关键和内存屏障(Memory Barrier)
332 0
高并发之volatile、synchronized关键和内存屏障(Memory Barrier)
|
Java C++
Juc19_从字节码角度看synchronize、Monitor类、monitorenter、monitorexit、深入理解同步方法(一)
①. 从字节码角度分析synchronized实现 ②. 反编译synchronized锁的是什么
161 0
Juc19_从字节码角度看synchronize、Monitor类、monitorenter、monitorexit、深入理解同步方法(一)