导航菜单
首页 » 无极登录网址 » 正文

everything-java内存模型详解(附面试标题剖析)

首先看一个面试标题,多线程环境下调用下面两个办法,终究履行结束后,r1和r2的值或许是什么?

面试标题

首先来剖析一下,多线程环境下不能确认办法履行的先后次序,假设method1履行完之后,再履行method2;那么终究r1和r2的值是1,0; 假如method2王瀚琨履行完之和,method1再履行,则是0,2;

当然也会有人想到两个办法替换履行,也便是履行完第4行代码之后,履行第9行代码;那么终究的值则是0,0;

但是以上答案并不是完全正确的,还有一种状况,终究r1 r2的值或许是1和2,为什么呢?怎么防止这种成果呈现呢?接下来从java内存模型来剖析;

java内存模型

怎么了解和界说java内存模型呢?

其中心是界说了特定操作的hapeverything-java内存模型详解(附面试标题剖析)peeverything-java内存模型详解(附面试标题剖析)ns-before联系,用来确保两个操作的可见性(无论是everything-java内存模型详解(附面试标题剖析)单线程或许多线程);

什么是happens-before?

界说是说假如B操作再A操作之后履行,那么B操作必定能够看到A操作的成果,这样咱们就说A操everything-java内存模型详解(附面试标题剖析)作happens-before B操作;

这儿举一个反例或许更好了解,比方上面的标题中,办法1将b赋值为1,这个操作完结之后,关于b的读取操作,在数据没有改写至主内存之前,那么读取操作是不能读到正确的值的。这儿的写操作与读操作就没有happens before联系;

那么java中界everything-java内存模型详解(附面试标题剖析)说了哪些happen-before联系呢?

  1. 同一个线程内部,各个操作之间的联系满意happens - before;
  2. volatile变量的写操作happens-before读操作
  3. 解锁操作happens-before加锁操作
  4. 目标构建完结,happens-before finalize操作
  5. 线程的发动,线程的操作,线程停止这三个操作由happens-before联系,具体来说便是start操作happens线程内的一切操作,线程内的操作happens-before停止操作(比方Thread.join操作)

现在来剖析开篇说到的,为什么终究成果有或许是1,2呢?

显然是第5行和第10行操作发生在了第4行和第9行之前。也便是履行次序与代码中的次序不一致,这儿很多人或许就想到是指令重排序原因导致的问题了;

也便是实践履行过程中,办法或许将两个句子次序换了,这并没有违背java虚拟机的准则,这儿要说到重排序的准则了。

java虚拟机重排序的准则

as-if-serial,也便是说在单线程环境下,排序前后的履行成果是相同的;

关于标题中的重排序是在这个准则下进行的,所以单线程下并没有什么问题;而多线程环境下会导致终究成果是1,2的问题;

怎么防止呈现1,2这种状况呢?

了解了happens-before准则就很简略了,将a,b两个变量用volatile润饰,防止重排序即可;

二维码