`

java线程安全总结 续(转载)

    博客分类:
  • JVM
阅读更多

转载自 ---- http://www.iteye.com/topic/808550

 

     站内很多人都问我,所谓线程的“工作内存”到底是个什么东西?有的人认为是线程的栈,其实这种理解是不正确的。看看JLS(java语言规范)对线程工作 内存的描述,线程的working memory只是cpu的寄存器和高速缓存的抽象描述。

 

      可能 很多人都觉得莫名其妙,说JVM的内存模型,怎么会扯到cpu上去呢?在此,我认为很有必要阐述下,免 得很多人看得不明不白的。先抛开java虚拟机不谈,我们都知道,现在的计算机,cpu在计算的时候,并不总是从内存读取数据,它的数据读取顺序优先级 是:寄存器-高速缓存-内存。线程耗费的是CPU,线程计算的时候,原始的数据来自内存,在计算过程中,有些数据可能被频繁读取,这些数据被存储在寄存器 和高速缓存中,当线程计算完后,这些缓存的数据在适当的时候应该写回内存。当个多个线程同时读写某个内存数据时,就会产生多线程并发问题,涉及到三个特 性:原子性,有序性,可见性。在《线程安全总结》这篇文章中,为了理解方便,我把原子性和有序性统一叫做“多线程执行有序性”。支持多线程的平台都会面临 这种问题,运行在多线程平台上支持多线程的语言应该提供解决该问题的方案。

 

       那么,我们看看JVM,JVM是一个虚拟 的计算机,它也会面临多线程并发问题,java程序运行在java虚拟机平台上,java程序员不可能直接去控制底层线程对寄存器高速缓存内存之间的同 步,那么java从语法层面,应该给开发人员提供一种解决方案,这个方案就是诸如 synchronized, volatile,锁机制(如同步块,就绪队 列,阻塞队列)等等。这些方案只是语法层面的,但我们要从本质上去理解它,不能仅仅知道一个 synchronized 可以保证同步就完了。   在这里我说的是jvm的内存模型,是动态的,面向多线程并发的,沿袭JSL的“working memory”的说法,只是不想牵扯到太多底层细节,因为 《线程安全总结》这篇文章意在说明怎样从语法层面去理解java的线程同步,知道各个关键字的使用场 景。

 

      今天有人问我,那java的线程不是有栈吗?难道栈不是工作内存吗?工作内存这四个字得放到具体的场景 中描述,方能体现它具体的意义,在描述JVM的线程同步时,工作内存指的是寄存器和告诉缓存的抽象描述,具体请自行参阅JLS。上面讲的都是动态的内存模 型,甚至已经超越了JVM的范围,那么JVM的内存静态存储是怎么划分的?今天还有人问我,jvm的内存模型不是有eden区吗?也不见你提起。我跟他 说,这是两个角度去看的,甚至是两个不同的范围,动态的线程同步的内存模型,涵盖了cpu,寄存器,高速缓存,内存;JVM的静态内存储模型只是一种对内 存的物理划分而已,它只局限在内存,而且只局限在JVM的内存。那些什么线程栈,eden区都仅仅在JVM内存。

 

      说说JVM的线程栈和有个朋友反复跟我纠结的eden区吧。JVM的内存,被划分了很多的区域:

1.程序计数器
每一个Java线程都有一个程序计数器来用于保存程序执行到当前方法的哪一个指令。
2.线程栈
线 程的每个方法被执行的时候,都会同时创建一个帧(Frame)用于存储本地变量表、操作栈、动态链接、方法出入口等信息。每一个方法的调用至完成,就意味 着一个帧在VM栈中的入栈至出栈的过程。如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果VM栈可以 动态扩展(VM Spec中允许固定长度的VM栈),当扩展时无法申请到足够内存则抛出OutOfMemoryError异常。
3.本地方法栈
4.堆

每 个线程的栈都是该线程私有的,堆则是所有线程共享的。当我们new一个对象时,该对象就被分配到了堆中。但是堆,并不是一个简单的概念,堆区又划分了很多 区域,为什么堆划分成这么多区域,这是为了JVM的内存垃圾收集,似乎越扯越远了,扯到垃圾收集了,现在的jvm的gc都是按代收集,堆区大致被分为三大 块:新生代,旧生代,持久代(虚拟的);新生代又分为eden区,s0区,s1区。新建一个对象时,基本小的对象,生命周期短的对象都会放在新生代的 eden区中,eden区满时,有一个小范围的gc(minor gc),整个新生代满时,会有一个大范围的gc(major gc),将新生代里的部分对象转到旧生代里。
5.方法区
其 实就是永久代(Permanent Generation),方法区中存放了每个Class的结构信息,包括常量池、字段描述、方法描述等等。VM Space描述中对这个区域的限制非常宽松,除了和Java堆一样不需要连续的内存,也可以选择固定大小或者可扩展外,甚至可以选择不实现垃圾收集。相对 来说,垃圾收集行为在这个区域是相对比较少发生的,但并不是某些描述那样永久代不会发生GC(至 少对当前主流的商业JVM实现来说是如此),这里的GC主要是对常量池的回收和对类的卸载,虽然回收的“成绩”一般也比较差强人意,尤其是类卸载,条件相 当苛刻。
6.常量池
 Class 文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量表(constant_pool table),用于存放编译期已可知的常量,这部分内容将在类加载后进入方法区(永久代)存放。但是Java语言并不要求常量一定只有编译期预置入 Class的常量表的内容才能进入方法区常量池,运行期间也可将新内容放入常量池(最典型的String.intern()方法)。

 

关于垃圾收集,在此不多说,流到垃圾收集那一章再详细说吧。关于java的同 步,其实还有基于CPU原语的比较并交换的非阻塞算法(CAS),不过这个在java的并发包里已经实现了很多,因此关于这点,就留到java并发包那一 章介绍吧。后面我会专门写一篇文章,JVM内存与垃圾收集。

分享到:
评论

相关推荐

    java线程安全总结.doc

    以下是对Java线程安全的深入总结: ### 一、线程安全的定义 线程安全是指当多个线程访问同一块代码时,如果每个线程都能得到预期的结果,且不产生数据不一致或同步问题,那么这块代码就被称为线程安全的。Java中的...

    JAVA多线程端点续传下载

    JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载JAVA多线程端点续传下载...

    java线程安全总结

    java线程安全总结 帮助你们更好的理解什么是线程 什么是网络安全

    java线程安全总结.pdf

    标题“java线程安全总结.pdf”指向了文档的主要内容:这是关于Java编程语言中的线程安全问题的总结性资料。线程安全是并发编程中的一个核心概念,它与Java多线程技术紧密相关。文档的描述信息非常简洁,只是重复了...

    java线程安全测试

    Java线程安全是多线程编程中的一个关键概念,它涉及到多个线程访问共享资源时可能出现的问题。在Java中,线程安全问题通常与并发、内存模型和可见性有关。Java内存模型(JMM)定义了如何在多线程环境下共享数据的...

    java线程安全总结.doc下载

    理解并熟练运用这些技术,能帮助开发者编写出高效、可靠的多线程Java程序。在实际项目中,应根据具体场景选择合适的线程安全策略,平衡性能和安全性。在进行性能优化时,也要注意避免过度设计,保持代码简洁。

    Java多线程与线程安全实践-基于Http协议的断点续传

    Java多线程与线程安全实践-基于Http协议的断点续传 Java多线程与线程安全实践-基于Http协议的断点续传 Java多线程与线程安全实践-基于Http协议的断点续传 Java多线程与线程安全实践-基于Http协议的断点续传 Java多...

    Java多线程与线程安全实践(基于Http协议的断点续传)源码.zip

    Java多线程与线程安全实践Java多线程与线程安全实践Java多线程与线程安全实践Java多线程与线程安全实践Java多线程与线程安全实践Java多线程与线程安全实践Java多线程与线程安全实践Java多线程与线程安全实践Java多...

    java线程安全性总结

    用思维导图将Java线程安全性相关基本概念联系起来

    JAVA多线程与线程安全实践-基于Http协议的断点续传.rar

    JAVA多线程与线程安全实践-基于Http协议的断点续传 JAVA多线程与线程安全实践-基于Http协议的断点续传 JAVA多线程与线程安全实践-基于Http协议的断点续传 JAVA多线程与线程安全实践-基于Http协议的断点续传 JAVA多...

    Java多线程与线程安全实践-基于Http协议的断点续传.zip

    Java多线程与线程安全实践-基于Http协议的断点续传Java多线程与线程安全实践-基于Http协议的断点续传Java多线程与线程安全实践-基于Http协议的断点续传Java多线程与线程安全实践-基于Http协议的断点续传Java多线程与...

    Java多线程编程总结

    - `java.util.concurrent.atomic` 包提供了原子类,用于在不需要锁的情况下进行线程安全的操作。 #### 二十、Java线程:新特征-障碍器 - `CyclicBarrier` 和 `Phaser` 类允许一组线程相互等待,直到所有线程到达一...

    java线程安全总结[汇编].pdf

    Java线程安全是多线程编程中的一个核心概念,...总结起来,Java线程安全是一个复杂而又重要的主题,涉及到多线程编程中的各种机制和策略。理解并掌握这些知识点,可以帮助开发者编写出高效、稳定、线程安全的Java程序。

    Java线程安全问题_动力节点Java学院整理

    其实java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改。总结java的内存模型,要解决两个主要的问题:可见性和有序性。我们都知道计算机有高速缓存...

    Java多线程与线程安全编程实践-基于Http协议的断点续传.zip

    Java多线程与线程安全编程实践-基于Http协议的断点续传.zip Java多线程与线程安全编程实践-基于Http协议的断点续传.zip Java多线程与线程安全编程实践-基于Http协议的断点续传.zip Java多线程与线程安全编程实践-...

    基于Http协议的断点续传-Java多线程与线程安全实践编程.zip

    基于Http协议的断点续传-Java多线程与线程安全实践编程.zip 基于Http协议的断点续传-Java多线程与线程安全实践编程.zip 基于Http协议的断点续传-Java多线程与线程安全实践编程.zip 基于Http协议的断点续传-Java多...

Global site tag (gtag.js) - Google Analytics