1.1,平台的内存模型:在共享内存的多处理器体系架构中,每个处理器都拥有自己的缓存,并且定期地与主内存进行协调。要想确保每个处理器都能在任意时刻知道其他处理器正在进行的工作,将需要非常大的开销。Java还提供了自己的内存模型,并且JVM通过在适当的位置插入内存栅栏来屏蔽在JMM与底层平台内存模型之间的差异。
1.2,重排序:同步将限制编译器、运行时和硬件对内存操作重排序的方式,从而在实施重排序时不会破坏JMM提供的可见性保证。
1.3,Java内存模型:Java内存模型是通过各种操作来定义的,包括对变量的读写操作,监视器的加锁和释放操作,以及线程的启动和合并操作。如果在读操作和写操作之间没有依照Happens-Before来排序,那么就会产生数据竞争问题,Happens-Before规则包括:程序顺序规则,监视器锁规则,volatile变量规则,线程启动规则,线程结束规则,中断规则,终结器规则,传递性。
1.4,借助同步:使用一种现有的Happens-Before顺序来确保对象X的可见性,而不是专门为了发布X而创建一种Happens-Before顺序。在类库中提供的Happens-Before排序包括:
1.4.1,将一个元素放入一个线程安全容器的操作将在另一个线程从该容器中获取这个元素的操作之前执行
1.4.2,在CountDownLath上的倒数操作将在线程的闭锁上的await方法中返回之前执行
1.4.3,释放Semaphore许可的操作将在从该Semaphore上获得一个许可之前执行
1.4.4,Future表示的任务的所有操作将在从Future.get中返回之前执行
1.4.5,向Executor提交一个Runnable或Callable的操作将在任务开始执行之前执行
1.4.6,一个线程到达CyclicBarrier或Exchanger的操作将在其他到达该栅栏或交换点的线程被释放之前执行。
2,发布,除了不可变对象以外,使用被另一个线程初始化的对象通常是不安全的,除非对象的发布操作是在使用该对象的线程开始使用之前执行。
3,初始化过程中的安全性,初始化安全性只能保证通过final域可达的值从构造过程完成时开始的可见性。对于通过final域可达的值,或者在构成过程完成后可能改变的值,必须采用同步来确保可见性
总结
Java内存模型说明了某个线程的内存操作在哪些情况下对于其他线程是课件的,其中包括确保这些操作是按着一种Happens-Before的偏序关系进行排序,而这种关系是基于内存操作和同步操作等级别来定义的。如果缺少充足的同步,那么当线程访问共享数据是,会发生一些非常奇怪的问题。