官方网站制作,临沂网站建设方案书,昆明seo,网站建设开发公司哪家好文章目录 1、先行发生原则happens-before2、happens-before总原则3、8条happens-before规则4、案例 1、先行发生原则happens-before 在Java中#xff0c;Happends-Before本质上是规定了一种可见性#xff0c; A Happends-Before B#xff0c;则A发生过的事情对B来说是可见的… 文章目录 1、先行发生原则happens-before2、happens-before总原则3、8条happens-before规则4、案例 1、先行发生原则happens-before 在Java中Happends-Before本质上是规定了一种可见性 A Happends-Before B则A发生过的事情对B来说是可见的不论A事件和B事件是否发生在同一个线程里。 happens-before体现的是对可见性和有序性的约束。happens-before是并发环境下两个操作是否可能存在冲突的判断依据 y一定等于5如果线程A的操作(x5先行发生于线程B的操作(yx或者说这两个事件存在先行发生原则那y5一定成立反之则不一定因为x5的改变可能还没从A线程的工作内存刷回主内存线程就暂时挂起了。
但如果Java内存模型中的有序性都得靠volatile和synchronized来实现就非常繁琐而且日常开发也没见处处加这些关键字这是因为谁先谁后在先行发生原则里已经立好了规矩。
2、happens-before总原则 1如果一个操作happens-before另一个操作那么第一个操作的执行结果将对第二个操作可见而且第一个操作的执行顺序排在第二个操作之前。 2 两个操作之间存在happens-before关系并不意味着一定要按照happens-before原则制定的顺序来执行如果重排序之后的执行结果与按照happens-before关系来执行的结果一致那么这种重排序并不非法 举例
值日表里写了周一张三周二李四但现在张三周一临时有事和李四换班后教室还是能打扫干净
3、8条happens-before规则 1 次序规则一个线程内按照代码顺序写在前面的操作先于写在后面的操作 直白讲就是同一个线程前面一个操作把变量x赋值为1那后面一个操作肯定知道x已经变成1了 2 锁定规则一个unLock操作先行发生于后面(这里的后面是指时间上的先后)对同一个锁的lock操作 直白说就是一定是A线程unlock后B线程才能对同一个锁lock
Lock lock new ReentrantLock();lock.lock();
try{}finally{//先lock.unlock();
}
//后
lock.lock();
try{}finally{lock.unlock();
}3 volatile变量规则 对一个volatile变量的写操作先行发生于后面对这个变量的读操作前面的写对后面的读是可见的这里的”后面“同样是指时间上的先后 4 传递规则如果操作A先行发生于操作B而操作B又先行发生于操作C则可以得出操作A先行发生于操作C 5 线程启动规则Thread对象的start()方法先行发生于此线程的每一个动作 执行顺序一定是第4行先第2行后
Thread t1 new Thread(() - {System.out.println(QWE); //后},t1);
t1.start(); //先6 线程中断规则对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生可以通过Thread.interrupted()检测到是否发生中断。 直白说检测到中断事件发生检测到中断标志位变了是先发生了interrupt方法的调用。一定是先发烧了温度计才能检测到体温变了。 7 线程终止规则线程中的所有操作都先行发生于对此线程的终止检测我们可以通过isAlive()等手段检测线程是否已经终止执行 直白说线程中的操作比如run方法体先全部执行完线程才终止 8 对象终结规则一个对象的初始化完成(构造函数执行结束) 先行发生于它的finalize()方法的开始 翻译肯定是先new了一个对象才能垃圾回收这个对象
4、案例
private int value 0;private int getValue(){return value;
}private int setValue(){return value;
}现在有线程A和线程B线程A在时间上先调用了setValue方法然后线程B调用同一对象的getValue方法那线程B的返回值是
对照上面的8条规则两个方法在不同线程第一条规则用不上两个方法都未加锁规则2也pass共享变量value没有加volatile规则3pass先行发生规则不等价于时间上的先这里目前直接没有已知的先行发生规则无从传递pass…
⇒ 无法通过happens-before原则推导出线程A happens-before线程B虽然可以确认在时间上线程A优先于线程B无法确认线程B获得的结果是什么所以这段代码不是线程安全的。
怎么修复?方式一加synchronized如下这样性能损失太大
private int value 0;private synchronized int getValue(){return value;
}private synchronized int setValue(){return value;
}方式二把value定义为volatile变量由于setter方法对value的修改不依赖value的原值满足volatile关键字使用场景
private volatile int value 0;private int getValue(){return value; //利用volatile保证读取操作的可见性
}private synchronized int setValue(){ //利用synchronized保证复合操作的原子性return value;
}利用volatile保证读取操作的可见性利用synchronized保证复合操作的原子性结合使用锁和volatile 变量来减少同步的开销