A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© darkads 中级黑马   /  2014-9-14 18:40  /  1003 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文


    Java堆:就是所有线程的共享空间,里面保存了创建的对象,还有运行时方法区和常量池
    运行时方法区:Class的内存结构信息,static字段及方法
    常量池:方法区的一部分,保存了class中的常量值:String,public static final字段
    Java虚拟机栈:每一个线程独有的运行栈,启动一个线程就创建一个,退出时销毁,主要保存线程的本地变量和局部变量值,后面会具体谈。
    线程PC寄存器:线程当前执行的字节码指令
    本地方法栈:调用JNI方法时创建,结束销毁

这张图是我自己使用Photoshop绘制的,非常基础的内容,但是Java内存结构在是非常重要的,很多地方均有涉及,例如下面这张图:

这张图说明了线程如何使用主内存中的数据
线程从主内存中读取一个值,为了方便,在高速缓存中做了一个副本,然后就直接使用这个副本值进行操作,操作结束后,再将副本值同步到主内存中。如果这期间变量值发生了改变,那么线程可能任然使用副本值进行操作得到了一个错误的值,并且会把它写入主内存,这时程序就会发生错误。所以Java提供了如下的解决方案:
     1.使用synchronized关键字,获得一个对象锁。实质上就是把上图中ticket变量所属对象监视起来,并且让线程直接访问主内存中的数据,如果这期间有其他线程来访问该对象,就让该线程进入等待,直到正在使用该对象的线程释放锁,这样就保证了数据的正确。
     2.把整个对象都监视起来会消耗很大的系统资源,而且有时候我们只想保证对象中的一个数据值的线程安全,那么对基本数据类型来说可以使用volatile关键字。它不会锁住整个对象,只保证了一条,让线程不创建该变量值的副本,直接访问主内存,这样就显得轻便了许多。
     3.volatile虽然方便但是它有一个问题,如果针对该变量的操作不是原子操作,即可以被CPU调度打断的操作,例如,int型数据的自增、自减操作,会导致volatile作用失效。这个时候就需要原子类:AtomicXX(XX表示Interger、Boolean等),
支持在单个变量上解除锁的线程安全编程。

大致就这么些吧,这是我这两天复习的成果了!大家一起加油,早日进入黑马!

1 个回复

倒序浏览
好像很牛的赶脚!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马