您的位置:首页 > 编程语言 > Java开发

《Java并发编程实战》第十六章 Java内存模型 读书笔记

2014-06-05 07:58 190 查看
Java内存模型是保障多线程安全的根基,这里仅仅是认识型的理解总结并未深入研究。

一、什么是内存模型,为什么需要它

Java内存模型(Java Memory Model)并发相关的安全发布,同步策略的规范、一致性等都来自于JMM。

1 平台的内存模型
在架构定义的内存模型中将告诉应用程序可以从内存系统中获得怎样的保证,此外还定义了一些特殊的指令(称为内存栅栏或栅栏),当需要共享数据时,这些指令就能实现额外的存储协调保证。
JVM通过在适当的位置上插入内存栅栏来屏蔽在JVM与底层平台内存模型之间的差异。

2 重排序
多个线程同时操作同一个变量时,读与写必须保证原子性,否则会出现读取的变量值并不是最新修改的等重排序问题。

深入理解Java内存模型(二)——重排序

3 Java内存模型简介
Happens-Before的规则包括:

程序顺序规则。如果程序中操作A在操作B之前,那么在线程中A操作将在B操作之前执行。

监视器锁规则。在监视器锁上的解锁操作必须在同一个监视器上的加锁操作之前执行。

Volative变量规则。对Volative变量的写入操作必须在对该变量的读操作之前执行。

线程启动规则。在线程上对Thread.Start的调用必须在线程中执行任何操作之前执行。

线程结束规则。在线程中的任何操作都必须在其他线程检测到该线程已结束之前执行,或者从Thread.join中成功返回,或者调用Threas.isAlive时返回false。

中断规则。当一个线程在另一个线程上调用interrupt时,必须在被中断线程检测到interrupt调用之前执行(通过抛出InterruptedException,或者调用isInterrupted和interrupted)。

终结器规则。对象的构造函数必须在启动该对象的终结器之前执行完成。

传递性。如果操作A在操作B之前执行,并且操作B在操作C之前执行,则操作A必须在操作C之前执行。

深入理解Java内存模型(一)——基础

4 借助同步
在类库中提供的其他Happens-Before排序包括:

将一个元素放入一个线程安全容器的操作将在另一个线程从该容器中获得这个元素的操作之前执行。

在CountDownLatch上的倒数操作将在线程从闭锁上的await方法中返回之前执行。

释放Semaphore许可的操作将在从该Semaphore上获得一个许可之前执行。

Future表示的任务的所有操作将在Future.get中返回之前执行。

向Executor提交一个Runnable或Callable的操作将在任务开始执行之前执行。

一个线程到达CyclicBarrier或Exchanger的操作将在其他到达该栅栏或交换点的线程被释放之前执行。如果CyclicBarrier使用一个栅栏操作,那么到达栅栏的操作将在栅栏操作之前执行,而栅栏操作又会在线程从栅栏中释放之前执行。

二、发布

1 不安全的发布
除了不可变对象以外,使用被另一个线程初始化的对象通常都是不安全的,除非对象的发布操作是在使用该对象的线程开始使用之前执行。

2 安全的发布

3 安全初始化模式

4 双重检查加锁

三、初始化过程中的安全性

参考资料:
深入理解Java内存模型

《深入理解Java虚拟机:JVM高级特性与最佳实践》 第五部分 高效并发
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: