“嗨,阿米戈!”

“有一个很大的话题——Java 内存模型。基本上,您还不必了解它,但了解它会很有帮助。”

“为了消除所有潜在的问题,Java 改变了它的内存管理机制。现在内存不再简单地分为线程的本地缓存和全局内存——这种机制甚至更好。”

“而且更复杂!”

“是的,更好,更复杂。就像飞机。坐飞机比走路好,但更复杂。我会尽量简单地解释新情况。”

“这就是他们想出的。一种用于同步本地线程内存的机制,称为‘happens-before’,被添加到代码中。发明了几个规则/条件。当满足这些条件时,内存同步或更新到当前状态。

“这是一个例子:”

命令 线程 1 线程 2
1
2

101
102
103
104
105

201
202
203
204
205
public int y = 1;
public int x = 1;

x = 2;
synchronized(mutex)
{
 y = 2;
}
线程正在等待互斥量被释放

synchronized(mutex)
{
 if (y == x)
 System.out.println("YES");
}

“这些条件之一是获取已释放的互斥量。如果释放并重新获取互斥量,则内存将在获取之前同步。线程 2 将看到变量 x 和 y 的‘最新’值,即使你不会宣布它们不稳定。”

“多么有趣!这些条件有很多吗?”

“够了——这里有一些同步记忆的条件:”

  • “在单个线程中,任何命令都发生在源代码中跟随它的任何操作之前。”
  • “锁的释放发生在获得同一个锁之前。”
  • “在同一监视器上输入同步块/方法 之前,会发生同步块/方法的退出。”
  • “将易失性字段写入内存发生在从内存中读取相同的易失性字段之前。”
  • “Thread 对象的 run 方法的结束发生在join() 方法结束或 isAlive() 方法在同一线程中的对象上返回 false 之前。”
  • “对 Thread 对象的 start() 方法的调用发生在run() 方法在同一线程中的对象上启动之前。”
  • “构造函数的结束发生在此类的 finalize() 方法开始之前。”
  • “对 interrupt() 方法的调用发生在线程确定已调用此方法之前,因为抛出 InterruptedException 或使用 isInterrupted() 或 interrupted() 方法。”

“所以,这一切比我想象的要复杂一点?”

“是的,有点复杂……”

“谢谢你,Rishi。我会考虑的。”

“这个话题你不用太在意,总有一天你会自己明白的。现在,你还是先了解一下基础知识,而不是钻到密林里去。 Java 机器的内部运作。Java 9 将发布,然后一切都会再次改变。”

“O_o。是的......有些事情最好不要知道。”