内存模型与多线程技术

上传人:jian****018 文档编号:157494623 上传时间:2022-09-29 格式:PPT 页数:48 大小:240KB
收藏 版权申诉 举报 下载
内存模型与多线程技术_第1页
第1页 / 共48页
内存模型与多线程技术_第2页
第2页 / 共48页
内存模型与多线程技术_第3页
第3页 / 共48页
资源描述:

《内存模型与多线程技术》由会员分享,可在线阅读,更多相关《内存模型与多线程技术(48页珍藏版)》请在装配图网上搜索。

1、研究院java内存模型与多线程技术研究院主要内容和目的学习java多线程理论基础:JMM(java内存模型)学习java多线程技术基础:理解同步是如和工作 分析程序什么时候需要同步澄清对volatile误解,正确使用Task Cancellation and Thread Shutdown策略Lazy initialization Safety技术研究院JMM(java内存模型)什么是Java内存模型Java内存模型相关概念java线程和内存交互行为定义Ordering&visibilityJMM相关java语言规范研究院内存模型 操作平台的内存模型 寄存器,CPU缓存,物理内存,虚拟内存 缓

2、存一致性模型 顺序一致性模型顺序一致性模型:要求对某处理机所写的值立即进行传播,在确保该值以被所有处理机接受后才能继续其他指令的执行 释放一致性模型释放一致性模型:允许将某处理机所写的值延迟到释放锁时进行传播研究院Java内存模型(JMM)内存存管理的跨平台统一的模型 write-once,run-anywhere concurrent applications in Java 定义了Java线程和内存交互的规则 通过一组语义规则来描述尤其是多线程之间共享内存的模式,保证多线程程序结果的可预测,语义一致 性 不同于其他语言,同平台无关 所有的实例变量,静态变量和数组元素数组元素都存放在堆内存里

3、 线程本地变量在堆栈中,不受JMM影响研究院Java内存模型相关概念Thread working copy memory在java规范中这是一个抽象的概念,对应可能会是寄存器,cpu缓存,编译及执行优化等。一个新产生的Thread有一个空的working memory。类似一个高速缓存线程之间无法相互直接访问,变量传递均需要通过主存完成 The main memory 就是我们所说的java堆内存 Threads execution engine保证线程的正确执行顺序研究院java线程和内存交互行为定义 JLS中对线程和主存互操作定义了6个行为,分别为load,save,read,write,

4、assign和use,这些操作行为具有原子性,且相互依赖,有明确的调用先后顺序 A use action(by a thread)transfers the contents of the threads working copy of a variable to the threads execution engine.An assign action(by a thread)transfers a value from the threads execution engine into the threads working copy of a variable.A read action

5、(by the main memory)transmits the contents of the master copy of a variable to a threads working memory for use by a later load operation.A load action(by a thread)puts a value transmitted from main memory by a read action into the threads working copy of a variable.A store action(by a thread)transm

6、its the contents of the threads working copy of a variable to main memory for use by a later write operation.A write action(by the main memory)puts a value transmitted from the threads working memory by a store action into the master copy of a variable in main memory.研究院java线程和内存交互分析例子分析:class Simpl

7、e int a=1,b=2;/Thread 1 executes void to()a=3;b=4;/Thread 2 executes void fro()System.out.println(a=+a+,b=+b);类似计算机多级存储器结构,Working Memory类似Cache机制问题:变量a,b何时写会main memory?研究院OrderingOrdering&visibilityvisibility 程序顺序:程序声明它们应当发生的顺序 执行顺序:JMM不保证线程对变量操作发生的顺序和被其他线程看到的是同样的顺序。JMM容许线程以写入变量时所不相同的次序把变量存入主存 线程内

8、部本身遵循程序顺序,从线程外看到的是执行顺序 编译器和处理器可能会为了性能优化,进行重新排序 程序执行为了优化也可能重新排序研究院OrderingOrdering&visibilityvisibility 多线程场景分析 class Simple int a=1,b=2;/Thread 1 executes void to()a=3;/This can appear to happen second b=4;/This can appear to happen first /Thread 2 executes void fro()System.out.println(a=+a+,b=+b);下

9、面哪种结果是正确的:a=1,b=2 a=1,b=4a=3,b=2a=3,b=4研究院Happens-Before Memory Model 类似释放一致性模型类似释放一致性模型 Partial ordering(happens-before):如果B能够看到A动作产生的结果,我们说A happens-before B,JMM定义了一些这样的规则,如:Program order rule.Each action in a thread happens-before every action in that thread that comes later in the program order.

10、Monitor lock rule.An unlock on a monitor lock happens-before every subsequent lock on that same monitor lock.Volatile variable rule.A write to a volatile field happens-before every subsequent read of that same field 研究院The rules for happens-before 研究院JMM相关java语言规范 JMM定义了保证内存操作跨线程的正确的Ordering和visibil

11、ity 方法 Java语言提供的技术和工具 synchronized 块 volatile 变量(在JDK5+的JVM中得到修补)工具类:原子变量 Final变量(在JDK5+的JVM中得到修补)研究院正确的理解synchronizedsynchronized 作用说明Synchronized内存模型语义分析如何判定多线程的程序何时需要Synchronized同步需求的JMM内存交互分析练习锁对象的引用在同步块中发生修改会出现什么?Hostspot JVM的synchronized优化技术直接使用synchronized 不足之处研究院synchronized 作用说明Low level lo

12、cking什么时候需要synchronized?一个变量有可能被多个线程访问,其中至少有一个线程是写操作每个对象对象都有一个相关的lock对象(监视器)java语言没有提供分离的lock和unlock操作,但是在JVM提供了两个单独的指令monitorenter和monitorext来实现特性 Atomicity:Locking to obtain mutual exclusion Visibility:Ensuring that changes to object fields made in one thread are seen in other threads(memory)Order

13、ing:Ensuring that you arent surprised by the order in which statements are executed Blocking:Cant interrupt 研究院Synchronized内存模型语义分析 Synchronized:通过对象引用找到同步对象,然后获取对象上的监视器进行锁操作 当线程进入synchronized 块之后首先要做的是清洗 threads working memory,对块内使用到的变量要么执行assign动作要么对use的变量执行 read-load原子操作从 main memory装载新的值 当线程退出sy

14、nchronized 块之前,对它在working memory中所有的 assigned values执行 store write原子操作,写回main memory 研究院Synchronized内存模型语义分析 Example:/block until obtain locksynchronized(obj)/get main memory value of field1 and field2 int x=obj.field1;int y=obj.field2;obj.field3=x+y;/commit value of field3 to main memory/release lo

15、ck研究院如何分析多线程并发需求 class SynchSimple int a=1,b=2;/Thread 1 executes synchronized void to()a=3;b=4;/Thread 2 executes void fro()System.out.println(a=+a+,b=+b);以下哪种结果是正确的?a=1,b=2 a=1,b=4a=3,b=2a=3,b=4这是一个线程安全的类吗?接下来我们通过JMM语义来分析这个例子研究院JMM内存交互分析研究院JMM内存交互分析 SynchSimple 分析:write a 和 write b 在synchronized 规

16、则中并没有规定发生的顺序约束 read a 和 read b.同样也没有规定发生的顺序 结果说明的什么问题?对一个方法声明synchronized 并不能够保证这个方法行为产生的结果是一个原子操作,也就是说write a 和 write b 两个操作在main memory不是原子行为,虽然单个都是原子操作。下面我们做一个练习:研究院JMM内存交互分析练习 Example:class Foo int a=1,b=2;synchronized void to()a=3;b=4;synchronized void fro()System.out.println(a=+a+,b=+b);分析结果是什

17、么?研究院问题?这个方法的同步块有可能被多个线程并发执行!这个方法的同步块有可能被多个线程并发执行!有可能在有可能在 size的条件下获得两把不同的锁的条件下获得两把不同的锁 锁对象的引用在同步块中发生修改会出现什么?锁对象的引用在同步块中发生修改会出现什么?public void foo(int isze)synchronized(intArr)size)int newIntArr=new intsize;System.arraycopy(intArr,0,newIntArr,0,intArr.length);intArr=newintArr;研究院直接使用synchronized 不足之处

18、和发展 不能够扩越多个对象 当在等待锁对象的时候不能中途放弃,直到成功 等待没有超时限制()不能中断阻塞 JDK5中提供更加灵活的机制:Lock和Condition synchronized在JDK6中性能将会有很大提升研究院Hostspot JVM的synchronized优化技术 锁省略锁省略:锁对象的引用时线程本地对象(线程的堆栈内的对象)public String getStoogeNames()Vector v=new Vector();v.add(Moe);v.add(Larry);v.add(Curly);return();研究院Hostspot JVM的synchronized

19、优化技术 锁粗化:锁粗化:锁粗化就是把使用同一锁对象的相邻同步块合并的过程public void addStooges(Vector v)v.add(Moe);v.add(Larry);v.add(Curly);研究院Hostspot JVM的synchronized优化技术 自适应锁优化技术自适应锁优化技术 实现阻塞有两种的技术,即让操作系统暂挂线程,直到线程被唤醒,或者使用旋转(spin)锁。旋转锁基本上相当于以下代码:while(lockStillInUse);Hotspot JVM可以对持有时间短的锁使用旋转,对持有时间长的锁使用暂挂。研究院理解和使用理解和使用VolatileVola

20、tile变量变量 Volatile变量的内存模型分析变量的内存模型分析 使用valatile JDK5的研究院VolatileVolatile变量的内存模型分析变量的内存模型分析“不要相信volatile”,这种说法已经过时 旧的内存模型:保证读写volatile都直接发生在main memory中,线程的working memory不进行缓存 仅仅保证这些volatile使用的价值和意义不大 在新的内存模型下对volatile的语义进行了修补和增强如果当线程 A 写入 volatile 变量 V 而线程 B 读取 V 时,那么在写入 V 时,A 可见的所有变量值现在都可以保证对 B 是可见的

21、。结果就是作用更大的 volatile 语义,代价是访问 volatile 字段时会对性能产生了一点点的影响。(A volatile var write happens-before read of the var)研究院VolatileVolatile变量的内存模型分析变量的内存模型分析 volatile 的旧语义只承诺正在读和写的变量的可见性,仍然参与排序。这样导致排序问题。新的内存模型修补了这一点 实际上,对 volatile 字段的每一次读或者写都像是“半个”同步。对 volatile 的读有与monitor enter的内存语义,对 volatile 的写有与monitor exit

22、的同样的语义。研究院Volatile Guarantees VisibilityVolatile Guarantees Visibility Stop 用volatile修饰来保证变量的写可见性class Task implements Runnable private volatile boolean stop=false;public void stop()stop=true;public void run()while(!stop)runTask();try Thread.sleep(100);private void runTask()/*.*/研究院Volatile Guarante

23、es OrderingVolatile Guarantees OrderingIf a thread reads data,there is a happens-before edge from write to read of ready that guarantees visibility of data(A volatile ready write happens-before read of the ready)研究院使用valatile volatile 变量+操作不是原子行为volatile int x=1;x+;/不是一个原子操作,需要多条指令 Volatile 变量比 sync

24、hronization要便宜很多 在jdk5中推荐采用 工作机制类似Volatile 同时提供了简单运算的原子行为研究院JDK5的 get()具有读取 volatile 变量的内存效果。set()具有写入(分配)volatile 变量的内存效果 支持操作:getAndSet getAndAdd addAndGet getAndDecrement getAndIncrement decrementAndGet incrementAndGet 只要你有足够的能力,用Atomic变量能够实现所有的同步研究院Cancellation and ShutdownCancellation and Shutd

25、own Task cancellation policy 设计Cancellation policy:Interruption正确处理InterruptedException研究院Cancellation and Shutdown clean up any work then terminate.(Safe terminate)为什么需要cancellable(中断正在进行的活动)User-requested cancellation Time-limited activities Application events Errors Shutdown 安全快速可靠结束一个线程是一个比较复杂的话

26、题 Java没有提供安全的强迫一个Thread结束的方法 Java provides interruption,a cooperative mechanism 研究院cancellation policy 设计 How:how other code can request cancellation When:when the task checks whether cancellation has been requested What:what actions the task takes in response to a cancellation request.研究院Example:ca

27、ncellation policy 设计class Task implements Runnable private volatile boolean stop=false;public void stop()stop=true;public void run()while(!stop)runTask();try Thread.sleep(100);private void runTask()/*.*/研究院Example:cancellation policy 设计分析 How,When,How?问题:polling loops,只有一个检查点 线程不能立刻结束,要等到检测的时候 遇到Blo

28、cking method有可能无法中止 检查的变量必须是volatile修饰的研究院Cancellation policy:Interruption 礼貌地劝告另一个线程在它愿意并且方便的时候停止它正在做的事情。(Interruption is a cooperative mechanism)Thread中断状态(interrupted status):线程的一个内部属性,类型:boolean,初始值:false.():设置interrupted status 为true研究院interruption Policy 分析 分析:()方法.interrupt()只是设置线程的中断状态。表示当前线

29、程应该停止运行。When:在()、()或()等方法中取消阻塞并抛出 InterruptedException,也可以程序检测:轮询中断状态:()读取并清除:()InterruptibleChannel(java.nio):Most standard Channels implement InterruptibleChannel 等待获取文件锁定时可以被另一个线程中断研究院Cancellation policy:Interruption Interruption is usually the most sensible way to implement cancellation 其他问题 不能打

30、断一些IO操作,比如文件操作 无法终止在synchronized块上锁住的Thread Synchronous socket I/O in 研究院InterruptedException 检查型异常:检查型异常:当线程在很长一段时间内一直处于正在等待、休眠或暂停状态((),Object.wait(long),Object.wait(long,int),Thread.sleep(long)),而另一个线程用 Thread 类中的 interrupt 方法中断它时,抛出该异常。阻塞(阻塞(blocking)方法方法 方法签名包括抛出 InterruptedException,调用一个阻塞方法则意味

31、着这个方法也是一个阻塞方法 当中断阻塞方法时,抛出当中断阻塞方法时,抛出InterruptedException Thread 在()和()等方法中支持的取消机制,表明可以提前返回。当一个阻塞方法检测到中断并抛出 InterruptedException 时,它清除中断状态研究院如何处理InterruptedException 错误的做法:swallow interruption requeststry Task task=();();catch(InterruptedException e)();研究院如何处理InterruptedException Restore the interrup

32、t如果真的要湮灭InterruptedException,应该保留被别人中断的证据,交给高层去决定。/恰当的做法:try Task task=();();catch(InterruptedException e)();Thread.currentThread().interrupt();Propagate the InterruptedException 重新抛出它,如果抛到顶层,可以结束当前线程研究院Double-Checked Locking 目的:在多线程应用中用来lazy initialization并保证Singlen 在java语言中DCL不成立/Broken multithrea

33、ded version/Double-Checked Locking idiomclass Foo private Helper helper=null;public Helper getHelper()if(helper=null)synchronized(this)if(helper=null)helper=new Helper();return helper;/other functions and members.研究院为什么在java语言中DCL不成立 Java 构造对象不是原子操作:先申请一块空内存将其地址赋予 对象引用 在对象引用所指的地址之上构建对象,调用构造函数初始化很多人提

34、供了很多方法来修复DCL,但是没有人能够成功行为正确的程序,但是增加了同步的负担 /Correct multithreaded version,but synchronized every time!class Foo private Helper helper=null;public synchronized Helper getHelper()if(helper=null)helper=new Helper();return helper;/other functions and members.研究院Initialize-On-Demand Holder Class idiomInitialize-On-Demand Holder Class idiomprivate static class LazySomethingHolder public static Something something=new Something();.public static Something getInstance()return;研究院几点建议 开发多线程系统一定要理解java的内存模型,那样你才能够正确地分析线程需求 尽量使用现成的解决方案,优化的前提是保证程序的正确性,其次才是提高程序的性能 缩小锁的作用范围 缩短锁的存在时间

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!