膳绫擎的语句,可以按照A->B->C履行,结不雅为3.14,然则也可以按照B->A->C的次序履行,因为A、B是两句自力的语句,而C则依附于A、B,所以A、B可以重排序,然则C却不克不及排到A、B的前面。JMM包管了重排序不会影响到单线程的履行,然则在多线程中却轻易出问题。 比如如许的代码:
- int a = 0;
- bool flag = false;
- public void write() {
- a = 2; //1
- flag = true; //2
- }
- public void multiply() {
- if (flag) { //3
- int ret = a * a;//4
- }
- }
如图所示,write办法里的1和2做了重排序,线程1先对flag赋值为true,随后履行到线程2,ret直接计算出结不雅,再到线程1,这时刻a才赋值为2,很明显迟了一步。 这时刻可认为flag加上volatile关键字,禁止重排序,可以确保法度榜样的有序性,也可以上重量级的synchronized和Lock来包管有序性,它们能包管那一块区域里的代码都是一次性履行完毕的。 别的,JMM具备一些先天的有序性,即不须要经由过程任何手段就可以包管的有序性,平日称为happens-before原则。<>定义了如下happens-before规矩:
1.法度榜样次序规矩: 一个线程中的每个操作,happens-before于该线程中的随便率性后续操作
2.监督器锁规矩:对一个线程的解锁,happens-before于随后对这个线程的加锁
3.volatile变量规矩: 对一个volatile域的写,happens-before于后续对这个volatile域的读
5.start()规矩: 如不雅线程A履行操作ThreadB_start()(启动线程B) , 那么A线程的ThreadB_start()happens-before 于B中的随便率性操作
面试官:volatile的两点内存语义能包管可见性和有序性,然则能包管原子性吗?
6.join()原则: 如不雅A履行ThreadB.join()并且成功返回,那么线程B中的随便率性操作happens-before于线程A大年夜ThreadB.join()操作成功返回。
7.interrupt()原则: 对线程interrupt()办法的调用先行产生于被中断线程代码检测到中断事宜的产生,可以经由过程Thread.interrupted()办法检测是否有中断产生
面试官:volatile关键字若何知足并发编程的三大年夜特点的?
那就要重提volatile变量规矩: 对一个volatile域的写,happens-before于后续对这个volatile域的读。 这条再拎出来说,其实就是如不雅一个变量声明成是volatile的,那么当我读变量时,老是能读到它的最新值,这里最新值是指不管其它哪个线程对该变量做了写操作,都邑急速被更新到主存里,我也能大年夜主存里读到这个刚写入的值。也就是说volatile关键字可以包管可见性以及有序性。 持续拿膳绫擎的一段代码举例:
- int a = 0;
- bool flag = false;
- public void write() {
- a = 2; //1
- flag = true; //2
- }
- public void multiply() {
- if (flag) { //3
- int ret = a * a;//4
推荐阅读
年前最后一场技巧盛宴 | 1月27日与京东、日记易技巧大年夜咖畅聊智能化运维成长趋势! ELF Binary Image Mapped Into MemoryKernel/User Memory Split内存治理是操作体系的核心义务;它对法>>>详细阅读
地址:http://www.17bianji.com/lsqh/40382.html
1/2 1