1、Java内存模型
Java包括内存模型规定了所有的变量(这里的变量与java编程中的变量略有区别,它包括了实例字段、静态字段和构成数据对象的元素,但不包括局部变量和方法参数,因为后者是线程私有的,不会被共享)都存储在主内存中,此外,每个线程还有自己的工作内存。
线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝。线程对变量的所有操作都在工作内存中进行,不同线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递都需要主内存来传递。线程、主内存、工作内存三者的交互关系如下图所示。
主内存、工作内存的划分与java堆、栈、方法区的划分不是同一个层次的内存划分。粗略来看,主内存主要对应于java堆中对象的实例数据部分,而工作内存则对应于虚拟机栈中的部分区域。
2、原子性、可见性和有序性
(1)原子性(Atomicity):Java内存模型要求lock、unlock、read、load、assign、use、store和write这八个操作具有原子性。因此可以认为基本数据类型的读写是具有原子性的(long和double的非原子性协定除外,但事实上这种情况非常罕见。因为尽管Java内存模型虽然允许虚拟机不把long和double变量的读写实现成原子操作,但“强烈建议”虚拟机实现为具有原子性的操作。目前各种商业机也几乎是这样做的)。
synchronized则从更大范围上通过lock和unlock操作来保证原子性。
如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎全用这个变量前,需要重新执行load或者assgin操作初始化变量的值;
对一个变量执行unlock操作前,必须先把此变量同步回主内存中(执行store和write操作)。
(2)可见性(Visibiliy):volatile、synchronized、final可以保证可见性。(final有一种例外,即初始化时,构造器把”this”的引用传递出去,造成this引用逃逸,其他线程有可能访问到“初始化了一半”的对象)。
(3)有序性(Ordering):本线程内观察,所有操作都是有序的;在一个线程中观察另一个线程,所以操作都是无序的(“指令重排序”和“工作内存与主内存同步延迟”)。
可以通过volatile(禁止重排序)和synchronized(同步块只能串行操作)来保证有序性。
3、先行发生原则
Java语言无须任何同步手段保障就能成立的先行发生规则如下:
(1)程序次序规则(Program Order Rule):一个线程内,按照程序代码顺序,书写在前面的操作先行发生于书写在后面的操作;
(2)管程锁定规则(Monitor Lock Rule):一个unlock操作先行发生于后面对同一个锁的lock操作;
(3)volatile变量规则(Volatile Variable Rule):volatile的写操作先行发生于后面对这个变量的读操作;
(4)线程启动规则(Thread Start Rule):Thread对象的start()方法先行发生于此线程的每一个动作;
(5)线程终止规则(Thread Termination Rule):线程中的所有操作都先行发生于此线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值等手段检测到线程已经终止执行;
(6)线程中断规则(Thread Interrupt Rule):对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupt()方法检测到是否有中断发生;
(7)对象终结规则(Finalizer Rule):一个对象的初始化完成(构造函数执行结束)先行发生于它的finzlize()方法的开始;
(8)传递性(Transitivity):如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。
时间上的先后顺序与先行发生原则之间基本没有太大的关系:一个操作“时间上的先发生”不代表这个操作是“先行发生”(如两个线程先后getter和setter一个属性值);一个操作“先行发生”也不代表这个操作“时间上先发生”(如两条不相关的赋值语句,不知道处理器会先执行那一条)。
4、线程优先级并不是太靠谱
原因在于:Java的线程是被映射到系统的原生线程上来实现的,所以线程调度最终还是由操作系统决定。换言之,优先级在不同的平台上可能不一样。如Java语言设置了10个优先级,Solaris中有2147483628(2的31次方)种优先级,但windows就只有7种(必然会预见现java中优先级不一样的,在windows中会一样)。
此外,优先级也可能被系统自行改变,如windows中的”优先级推进器”(Priority Boosting)。
相关推荐
#### 第十二周:数据结构与算法复杂度 - 深入学习数组、链表、栈、队列等数据结构。 - 理解时间复杂度和空间复杂度,优化算法性能。 ### 三、学习资源 #### 教材推荐 - Walter Savitch,《Absolute Java》(第4版)...
2. **环境配置**:学习Java的第一步是安装Java Development Kit (JDK)并配置环境变量,包括设置JAVA_HOME、PATH和CLASSPATH等,确保能够运行Java编译器javac和Java虚拟机java。 3. **基础语法**:笔记会详细讲解...
### 第十二章:正则表达式 - **模式匹配**:使用`Pattern`和`Matcher`类。 - **替换操作**:替换字符串中的模式。 ### 第十三章至第十五章:Web前端技术 - **HTML**:标记语言,构建网页结构。 - **CSS**:样式表...
多线程是Java并发编程的基础,本章探讨了如何在Java中创建与管理线程,理解线程生命周期,以及如何实现线程同步与通信,提高程序的执行效率与响应速度。 #### 第六章:常用类API 本章涵盖了Java标准库中的重要类与...
12. **Java虚拟机(JVM)**:理解JVM的工作原理,包括类加载机制、内存模型(堆、栈、方法区等)、垃圾回收(GC)和性能调优策略。 13. **Java集合框架中的并发容器**:如ConcurrentHashMap、CopyOnWriteArrayList...
9. **JVM原理**:理解Java虚拟机的工作原理,包括类加载、内存模型、垃圾回收等,有助于优化程序性能。 10. **泛型**:泛型是Java SE 5.0引入的新特性,它允许在定义类、接口和方法时使用类型参数,增强了类型安全...
│ 高并发编程第一阶段09讲、多线程与JVM内存结构的关系,虚拟机栈实验.mp4 │ 高并发编程第一阶段10讲、Thread构造函数StackSize详细讲解.mp4 │ 高并发编程第一阶段11讲、Thread构造函数StackSize详细讲解-续....
12. **Java虚拟机(JVM)**:JVM是Java程序运行的平台,负责类的加载、验证、解析、执行以及垃圾回收。理解JVM的工作原理和内存模型对性能优化至关重要。 13. **Java EE**:对于Web开发,Java EE(Enterprise ...
#### 第十二章 正则表达式 - 正则表达式是文本匹配的强大工具。 - Java中的正则表达式通过`java.util.regex`包提供。 #### 第十三章 HTML语言 - HTML是超文本标记语言,用于构建网页的基本结构。 - Java开发者...
9. **JVM内存模型**:理解Java虚拟机(JVM)的工作原理,特别是堆、栈、方法区等内存区域,以及垃圾收集机制,对于性能优化至关重要。 10. **设计模式**:设计模式是解决常见编程问题的模板,如单例、工厂、观察者...
#### 第十二章:正则表达式 - **正则表达式介绍**:正则表达式是一种强大的文本匹配工具,Java中通过java.util.regex包提供的类来实现正则表达式的操作。 #### 第十三章至第十五章:Web前端技术 - **...
### Java实战经典学习笔记知识点概览 #### 一、Java概述及开发环境搭建 - **Java概述** - Java是一种广泛使用的高级编程语言,由Sun Microsystems于1995年发布。 - Java的设计目标是“一次编写,到处运行”,这...
你会了解Java的跨平台特性,即“一次编写,到处运行”的理念,以及Java如何通过JVM(Java虚拟机)实现这一目标。 2. **环境配置**:在开始编程之前,你需要设置Java开发环境。笔记会指导你下载并安装JDK(Java ...
8. **JVM与内存管理**:深入理解Java虚拟机(JVM)的工作原理,包括类加载机制、内存模型、垃圾回收,可以帮助优化程序性能。 9. **反射与动态代理**:Java的反射机制允许在运行时检查类和接口,创建和调用对象,这...
#### 第十二章:正则表达式 - **正则表达式基础:** 正则表达式用于匹配文本中的模式。 - **Pattern与Matcher:** `Pattern`类用于编译正则表达式,`Matcher`类用于匹配文本。 #### 第十三章:HTML语言 - **HTML...
13. **Java虚拟机(JVM)**:理解JVM的工作原理,包括类加载机制、内存模型(堆、栈、方法区等)和垃圾回收机制,有助于优化程序性能。 这个压缩包的学习资料将涵盖以上这些Java基础知识点,帮助初学者建立起坚实的...
Java程序通过Java虚拟机(JVM)运行,使得“一次编写,到处运行”成为可能。 2. **Java环境配置** 在开始学习Java之前,我们需要安装Java Development Kit (JDK),它包含了编译、运行Java程序所需的工具。同时,...