33JVM线程资源同步及交互机制.docVIP

  • 6
  • 0
  • 约3.15千字
  • 约 3页
  • 2017-06-07 发布于重庆
  • 举报
33JVM线程资源同步及交互机制

3.3? JVM线程资源同步及交互机制 Java程序采用多线程的方式来支撑大量的并发请求处理,程序在多线程方式执行的情况下,复杂程度远高于单线程串行执行的程序。尤其是在多核或多 CPU系统中,多线程执行的程序所带来的最明显的问题是线程之间共同管理的资源的竞争及线程之间的交互。JVM的线程实现及调度方式(抢占式、协作式)取决于操作系统,超出了本书范围,本节中仅介绍JVM线程资源同步机制和线程之间的交互机制。 3.3.1? 线程资源同步机制 首先来看典型获取下一ID的程序: int i 0 ; public int getNextId return i++; 以下为上面程序在JVM中的执行步骤: 1) JVM首先在main memory(JVM堆) 给i分配一个内存存储场所,并存储其值0; 2)线程启动后,会自动分配一片working memory区(通常是操作数栈),当线程执行到return i++时,JVM中并不是简单的一个步骤就可以完成的。i++动作在JVM中分为装载i、读取i、进行i+1操作、存储i及写入i五个步骤才得以完成。 装载i 线程发起一个装载i的请求给jvm线程执行引擎,引擎接收请求后会向main memory发起一个read i的指令。 当read i执行完毕后,一段时间线程会将i的值从main memory区复制到working memory区中。 读取i 此步负责的是从main memory中读取i。 进行i+1操作 此步由线程完成。 存储i 将i+1的值赋给i,然后存储到working memory中。 写入i 一段时间后i的值会写回到main memory中。 从以上步骤描述来看,这里面最关键的问题有两点:一是working memory中i值和main memory中的i值的同步是需要时间的;二是i++由多个操作组成。只要多个线程在这个时间段内同时执行了操作,就会出现获取i值相同的现象。举个简单的例子:假设线程A已执行i+1操作,但尚未执行完写入i步骤,线程B就完成了装载i的过程,那么当线程B执行完毕时,其得到的值和A就是一样的了,这是以上代码在多线程执行时会出现获取相同值的原因。 JVM把对于working memory的操作分为了use、assign、load、store、lock和unlock,对于working memory的操作的指令由线程发出,对于main memory的操作分为了read、write、lock和unlock;对于main memory的操作的指令由线程执行引擎发出 ,其含义分别为: use use由线程发起,需要完成将变量的值从working memory中复制到线程执行引擎中。 assign assign由线程发起,需要完成将变量值复制到线程的working memory中,例如a i,这时线程就会发起一个assign动作。 load load由线程发起,需要完成将main memory中read到的值复制到working memory中。 store store由线程发起,负责将变量的值从working memory中复制到main memory中,并等待main memory通过write动作写入此值。 read read由main memory发起,负责从main memory中读取变量的值。 write write由main memory发起,负责将working memory的值写入到main memory中。 lock lock动作由线程发起,同步操作main memory,给对象加上锁。 unlock unlock动作由线程发起,同步操作main memory,去除对象的锁。 JVM中保证以下操作是顺序的: 1)同一个线程上的操作一定是顺序执行的; 2)对于main memory上的同一个变量的操作一定是顺序执行的,也就是不可能两个请求同时读取变量值; 3)对于加了锁的main memory上的对象操作,一定是顺序执行的,也就是两个以上加了lock的操作,同时肯定只有一个是在执行的。 为了避免资源操作的脏数据问题,JVM提供了synchronized关键字、volatile关键字和lock/unlock机制。 采用synchronized关键字改造上面的代码为: public synchronized int getNextId return i++; 当多线程执行此段代码时,线程A执行到getNextId 方法,JVM知道该方法上有synchronized关键字,于是在执行其他动作前首先按照对象的实例ID加上一个lock。然后再继续执行return i++,而此时如线程B并发访问getNext

文档评论(0)

1亿VIP精品文档

相关文档