- 浏览: 149468 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
EclipseEye:
fair_jm 写道不错 蛮详细的 谢谢分享
SWT/JFace专题 --- SWT中Display和多线程 -
fair_jm:
不错 蛮详细的 谢谢分享
SWT/JFace专题 --- SWT中Display和多线程
Java 内存模型
--------------
内存模型描述的是程序中各变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存取出变量这样的低层细节。对象最终存储在内存中,但编译器、运行库、处理器或缓存可以有特权定时地在变量的指定内存位置存入或取出变量值。
------------------------
可见性
- - - - - - -
1. 同步与可见性(visibility)
synchronized 关键字强制实施一个互斥锁(互相排斥),这个互斥锁防止每次有多个线程进入一个给定监控器所保护的同步语句块。但是同步还有另一个方面:正如 JMM 所指定,它强制实施某些"内存可见性规则"。它确保了当存在一个同步块时缓存被更新,当输入一个同步块时缓存失效。
因此,在一个由给定监控器保护的同步块期间,一个线程所写入的值对于其余所有的执行由同一监控器所保护的同步块的线程来说是可见的。它也确保了编译器不会把指令从一个同步块的内部移到外部(虽然在某些情况下它会把指令从同步块的外部移到内部)。JMM 在缺乏同步的情况下不会做这种保证 —— 这就是只要有多个线程访问相同的变量时必须使用同步(或者它的同胞,易失性)的原因。
2. Volatile 与可见性
特别是,内存模型定义了保证内存操作跨线程的可见性的 volatile 、 synchronized 和 final 的语义。
volatile 语义保证 volatile 字段的读写直接在主存而不是寄存器或者本地处理器缓存中进行,并且代表线程
对 volatile 变量进行的这些操作是按线程要求的顺序进行的。
-----------------
发生前关系(happen-before)
-----------
像对变量的读写这样的操作,在线程中是根据所谓的“程序顺序”——程序的语义声明它们应当发生的顺序——排序的。在不同线程中的操作完全不一定要彼此排序——如果启动两个线程并且它们对任何公共监视器都不用同步执行、或者不涉及任何公共 volatile 变量,则完全无法准确地预言一个线程中的操作(或者对第三个线程可见)相对于另一个线程中操作的顺序。
排序保证是在线程启动、一个线程参与另一个线程、一个线程获得或者释放一个监视器(进入或者退出一个同步块)、或者一个线程访问一个 volatile 变量时创建的。JMM 描述了程序使用同步或者 volatile 变量以协调多个线程中的活动时所进行的顺序保证。新的JMM 非正式地定义了一个名为 happens-before 的排序,它是程序中所有操作的部分顺序。
1) 一个线程中的每个操作“发生之前”于这个线程程序规定的其他后续出现的操作。
2) 对监视器的解锁“发生之前”于同一监视器上的所有后续锁定。
3) 对 volatile 变量的写“发生之前”于同一 volatile 变量 的每一个后续读。
4) 一个线程的 Thread.start()调用“发生之前”于这个启动后的线程的其他操作。
5) 线程中的所有操作“发生之前” 从这个线程的 Thread.join() 成功返回的所有其他线程。
-----------------------------
初始化安全性
--------------
JMM 还寻求提供一种新的初始化安全性保证——只要对象是正确构造的,然后所有线程都会看到在构造函数中设置的final 字段的值,不管是否使用同步在线程之间传递这个引用。
而且,所有可以通过正确构造的对象的 final 字段可及的变量,如用一个 final 字段引用的对象的 final 字段,也保证对其他线程是可见的。
这意味着如果 final 字段包含,比如说对一个 LinkedList 的引用,除了引用的正确的值对于其他线程是可见的外,这个 LinkedList 在构造时的内容在不同步的情况下,对于其他线程也是可见的。 可以不用同步安全地访问这个 final 字段,编译器可以假定 final 字段将不会改变,因而可以优化多次提取。
在构造函数的 final 字段的写与在另一个线程中对这个对象的共享引用的初次装载之间有一个类似于 happens-before 的关系。当构造函数完成任务时,对 final 字段的所有写(以及通过这些 final 字段间接可及的变量)变为“冻结”,所有在冻结之后获得对这个对象的引用的线程都会保证看到所有冻结字段的冻结值。初始化 final 字段的写将不会与构造函数关联的冻结后面的操作一起重新排序。
初始化安全性保证了在多线程共享情况下不可变对象的正确构造。
--------------
内存模型描述的是程序中各变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存取出变量这样的低层细节。对象最终存储在内存中,但编译器、运行库、处理器或缓存可以有特权定时地在变量的指定内存位置存入或取出变量值。
------------------------
可见性
- - - - - - -
1. 同步与可见性(visibility)
synchronized 关键字强制实施一个互斥锁(互相排斥),这个互斥锁防止每次有多个线程进入一个给定监控器所保护的同步语句块。但是同步还有另一个方面:正如 JMM 所指定,它强制实施某些"内存可见性规则"。它确保了当存在一个同步块时缓存被更新,当输入一个同步块时缓存失效。
因此,在一个由给定监控器保护的同步块期间,一个线程所写入的值对于其余所有的执行由同一监控器所保护的同步块的线程来说是可见的。它也确保了编译器不会把指令从一个同步块的内部移到外部(虽然在某些情况下它会把指令从同步块的外部移到内部)。JMM 在缺乏同步的情况下不会做这种保证 —— 这就是只要有多个线程访问相同的变量时必须使用同步(或者它的同胞,易失性)的原因。
2. Volatile 与可见性
特别是,内存模型定义了保证内存操作跨线程的可见性的 volatile 、 synchronized 和 final 的语义。
volatile 语义保证 volatile 字段的读写直接在主存而不是寄存器或者本地处理器缓存中进行,并且代表线程
对 volatile 变量进行的这些操作是按线程要求的顺序进行的。
-----------------
发生前关系(happen-before)
-----------
像对变量的读写这样的操作,在线程中是根据所谓的“程序顺序”——程序的语义声明它们应当发生的顺序——排序的。在不同线程中的操作完全不一定要彼此排序——如果启动两个线程并且它们对任何公共监视器都不用同步执行、或者不涉及任何公共 volatile 变量,则完全无法准确地预言一个线程中的操作(或者对第三个线程可见)相对于另一个线程中操作的顺序。
排序保证是在线程启动、一个线程参与另一个线程、一个线程获得或者释放一个监视器(进入或者退出一个同步块)、或者一个线程访问一个 volatile 变量时创建的。JMM 描述了程序使用同步或者 volatile 变量以协调多个线程中的活动时所进行的顺序保证。新的JMM 非正式地定义了一个名为 happens-before 的排序,它是程序中所有操作的部分顺序。
1) 一个线程中的每个操作“发生之前”于这个线程程序规定的其他后续出现的操作。
2) 对监视器的解锁“发生之前”于同一监视器上的所有后续锁定。
3) 对 volatile 变量的写“发生之前”于同一 volatile 变量 的每一个后续读。
4) 一个线程的 Thread.start()调用“发生之前”于这个启动后的线程的其他操作。
5) 线程中的所有操作“发生之前” 从这个线程的 Thread.join() 成功返回的所有其他线程。
-----------------------------
初始化安全性
--------------
JMM 还寻求提供一种新的初始化安全性保证——只要对象是正确构造的,然后所有线程都会看到在构造函数中设置的final 字段的值,不管是否使用同步在线程之间传递这个引用。
而且,所有可以通过正确构造的对象的 final 字段可及的变量,如用一个 final 字段引用的对象的 final 字段,也保证对其他线程是可见的。
这意味着如果 final 字段包含,比如说对一个 LinkedList 的引用,除了引用的正确的值对于其他线程是可见的外,这个 LinkedList 在构造时的内容在不同步的情况下,对于其他线程也是可见的。 可以不用同步安全地访问这个 final 字段,编译器可以假定 final 字段将不会改变,因而可以优化多次提取。
在构造函数的 final 字段的写与在另一个线程中对这个对象的共享引用的初次装载之间有一个类似于 happens-before 的关系。当构造函数完成任务时,对 final 字段的所有写(以及通过这些 final 字段间接可及的变量)变为“冻结”,所有在冻结之后获得对这个对象的引用的线程都会保证看到所有冻结字段的冻结值。初始化 final 字段的写将不会与构造函数关联的冻结后面的操作一起重新排序。
初始化安全性保证了在多线程共享情况下不可变对象的正确构造。
发表评论
-
Nio Socket
2013-05-16 05:53 0asfda -
结合jdk源码解读,Error Exception
2013-05-10 04:00 0/* * @(#)Error.java 1.17 05/11 ... -
从不同的角度,重新审视class和interface
2013-05-07 03:40 0java开发中,对应class和interface的基本区别都 ... -
java.lang.Object
2013-05-07 03:35 0/* * @(#)Object.java 1.73 06/0 ... -
反射机制+类加载机制
2013-02-18 01:30 0反射机制+类加载机制 -
Eclipse Job并发框架专题
2013-02-18 00:43 01并发性架构 2使用作业 3用户交互选项 4作业的冲突管 ... -
并发专题----使用开源软件Amino构建并发应用程序/多线程运行时分析工具MTRAT
2013-02-14 00:50 1371使用开源软件构建并发 ... -
并发专题 ---- 线程安全
2013-02-14 00:50 747线程安全 ================== ... -
并发专题 --- 锁
2013-02-14 00:50 802相比于synchronized,ReentrantLock 提 ... -
并发专题 ---java.util.concurrent 包
2013-02-13 02:26 1832java.util.concurrent 包 原 ... -
并发专题---并发基础概念
2013-02-13 02:26 576进程VS程序 --进程是执行程序的动态过程,而程序是进程运行的 ... -
集合框架 Queue篇(8)---PriorityBlockingQueue、SynchronousQueue
2013-02-07 12:40 1308Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(7)---LinkedBlockingDeque
2013-02-07 12:40 850Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(6)---LinkedBlockingQueue
2013-02-07 12:39 827Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(5)---ArrayBlockingQueue
2013-02-06 10:39 701Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(4)---阻塞队列和生产者-消费者模式、DelayQueue
2013-02-06 10:39 994Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(3)---ConcurrentLinkedQueue
2013-02-06 10:38 1044Queue ------------ 1.ArrayDequ ... -
集合框架 Queue篇(2)---PriorityQueue
2013-02-06 10:38 831Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(1)---ArrayDeque
2013-02-06 10:38 927Queue ------------ 1.ArrayDeq ... -
集合框架 Set篇---HashSet、LinkedHashSet、TreeSet、CopyOnWriteArraySet、ConcurrentSkipList
2013-02-05 08:43 1480Set --------- 1.HashSet 2.Link ...
相关推荐
Java内存模型,简称JMM(Java Memory Model),是Java虚拟机规范中定义的一个抽象概念,它描述了在多线程环境下,如何保证各个线程对共享数据的一致性视图。JMM的主要目标是定义程序中各个变量的访问规则,以及在...
深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发可见性、有序性、原子性与JMM内存模型深入理解并发...
近期,在诚信通开源研究小组的专题学习分享会上,我们针对Java内存模型(JMM)进行了深入探讨,现将JMM相关的一些核心概念进行梳理,以便更好地理解和把握JMM的基本原理。 #### 第一问:JMM是干什么的? JMM (Java ...
本篇文章将深入探讨Java内存模型(JMM, Java Memory Model),以及其中的内存操作规则。 Java内存模型定义了在并发环境中,如何在不同线程之间共享数据以及保证数据一致性的一组规范。它主要关注的是处理器内存和...
在深入理解Java内存模型(JMM)及并发三大特性方面,我们需要先建立对多线程、共享内存模型、可见性、有序性和原子性的基础概念。Java内存模型是Java并发编程的核心,它定义了共享变量在多线程环境中的行为规则和...
Java内存模型,简称JMM(Java Memory Model),是Java编程语言规范的一部分,它定义了程序中各个线程如何访问和修改共享变量,以及如何确保数据的一致性。深入理解Java内存模型对于编写高效的并发程序至关重要。本文...
本文将深入探讨`concurrentMap`在Java内存模型(JMM,Java Memory Model)中的实现原理,以及如何通过HotCode优化并发性能。 Java内存模型定义了线程之间的共享变量访问规则,确保在多线程环境下正确地同步数据。...
Java 中的并发机制主要通过 Java 内存模型(JMM)和 Happens-Before 规则来实现。JMM 定义了 Java 程序中的内存模型,规定了变量的存储和读取规则。Happens-Before 规则则规定了操作的执行顺序和可见性规则。 线程...
Java内存模型(JVM Memory Model,简称JMM)是Java平台中的一个重要概念,它定义了程序中各个变量的访问规则,以及在多线程环境下的内存一致性效果。JMM主要解决的是并发环境下不同线程之间如何共享数据以及如何保证...
Java内存模型(JMM)是Java虚拟机规范的一部分,用于定义程序中各个线程对共享变量的访问规则,包括线程之间的通信、内存可见性和原子性等问题。 首先,Java内存模型规定了三个主要区域:程序计数器、虚拟机栈、...
除此之外,Java内存模型(JMM)是理解并发编程中的另一个核心概念。它定义了线程如何共享和访问内存,包括volatile变量的使用,这确保了不同线程之间的可见性。理解JMM可以帮助我们编写出更健壮的并发代码,避免因...
9. **JVM内存模型**:Java内存模型(JMM)是理解并发行为的基础,笔记会解释其工作原理,特别是 volatile 的内存语义。 10. **并发性能优化**:笔记会探讨如何通过优化并发策略来提高程序性能,例如减少锁的竞争、...
Java内存模型是并发编程中一个至关重要的概念,它定义了共享变量的访问规则,以及这些变量如何在多线程环境下进行读写操作。在深入理解Java内存模型之前,我们需要先了解并发编程模型的分类,然后掌握Java内存模型的...
Java内存模型(Java Memory Model,简称JMM)是Java并发编程中的核心概念,它定义了Java程序中多线程间共享变量的访问规则。理解JMM对于编写正确、高效的并发程序至关重要。本文将深入探讨JMM的原理、特性以及如何在...
- **Java内存模型(JMM)**:理解JMM对变量可见性、有序性和原子性的保证。 - **volatile关键字**:学习volatile的语义,如何解决线程间通信问题。 - **指令重排序**:了解编译器和处理器为了优化性能可能进行的...
在并发领域,"并发面试专题.pdf"可能会包含线程安全、锁机制、并发工具类如Semaphore、CountDownLatch和CyclicBarrier,以及Java内存模型(JMM)等内容。求职者需要了解如何避免死锁,掌握线程池的工作原理,以及...
Java内存模型(JMM)是Java虚拟机(JVM)的一部分,它定义了程序中不同变量如何交互,特别是在多线程环境下。JMM确保了在各种硬件和操作系统平台上,Java程序的行为具有一致性和可预测性。Java内存模型的主要目标是...
Java内存模型(JMM,Java Memory Model)是Java平台中用于描述如何在多线程环境中管理内存的一套规范。它确保了并发编程时不同线程之间的数据一致性、可见性和原子性,以避免出现数据竞争和其他并发问题。以下是JMM...
Java内存模型,简称JMM(Java Memory Model),是Java编程语言规范的一部分,它定义了线程如何共享和访问内存,以及在并发编程中如何处理数据一致性的问题。理解JMM对于编写高效、线程安全的Java代码至关重要。 1. ...
Java内存模型(JMM)是并发编程中的核心概念,它通过定义线程与主内存之间的交互规则,确保了多线程程序的正确性和内存的一致性。理解JMM的工作原理和特性,对于编写高效、可靠的并发程序至关重要。通过使用volatile...