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

Java虚拟机——Java内存模型与线程 [待更新]

2017-08-23 16:16 204 查看
12.2硬件的效率与一致性

处理器与内存速度矛盾-->

1.引入高速缓存-->新的问题:缓存一致性(Cache
Coherence)

 

2.指令重排优化(
Instruction Reorder)

保证结果与顺序执行结果一致,但不保证程序中各个语句计算先后顺序与输入代码的顺序一致.

 

12.3 Java内存模型(
Java Memory Model, JMM)

屏蔽屌各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果.

 

12.3.3 volatile型变量的特殊规则

1.保证此变量对所有线程的可见性.(当一条线程修改了这个变量的值,新值对于其他线程是可以立刻得知的.)

2.禁止指令重排优化.

对于第二点,有一个非常经典的例子就是DCL
(double check lock)的使用.

如下:

public static SingletongetInstance()

{

if (instance == null)

{

synchronized(Singleton.class) { //1

if (instance == null) //2

instance = new Singleton(); //3

}

}

return instance;

}

 

  因为Instruction
Reorder的关系,其中的instance=new
Singleton ()会出一点问题:

这句假设分为三步

1.先申请内存 2.构造Singleton
3.将instance指向新的内存区域
如果不进行指令重排,这个是没问题的.
如果指令重排后执行顺序是. 1 3 2.这就导致执行3后,instance已经非null,此时若恰好有别的线程重新访问get_instance函数.将得到instance非null的结果,并此时返回一个还没执行完构造函数的instance实例.从而出错.
但是volatile关键字的第二个语义,便是‘禁止指令重排优化’.
因此,如果把instance变量声明为
volatile , 双重检测法似乎也是work的.
如下:

private static volatile Singleton instance;

 

 
12.3.5 原子性可见性
有序性
12.3.6 先行发生原则
                1.程序次序规则             (控制流顺序)
                2.管程锁定规则             (同一个锁中unlock先于下一个lock)
                3.volatile变量规则        (写操作先于读操作)
                4.线程启动规则
                5.线程终止规则
                6.线程中断规则
                7.对象终结规则
                8.传递性
 
 
12.4 Java与线程
               
13.2 线程安全
13.2.1五类划分
                13.2.2实现线程安全的方法
                               1互斥同步
                                               Synchronize关键字

1.      synchronize同步块对同一线程是可重入的,不会锁死自己

2.      同步块在已进入的线程执行完之前,会阻塞后面的其他线程进入

3.      阻塞或唤醒线程需要从用户态转到和心态,因此可能耗费很多时间,
synchronize是一个重量级(Heavyweight)的操作
 
2 非阻塞同步
13.3锁优化
                1.自旋锁与自适应自旋(忙循环以避免挂起,恢复线程)
                2.锁消除 (虚拟机的优化)
                3.锁粗化 (避免频繁lock与unlock)
                4.轻量轻锁
                5.偏向锁
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: