内存模型与多线程技术

上传人:桔**** 文档编号:569161512 上传时间:2024-07-27 格式:PPT 页数:48 大小:265.52KB
返回 下载 相关 举报
内存模型与多线程技术_第1页
第1页 / 共48页
内存模型与多线程技术_第2页
第2页 / 共48页
内存模型与多线程技术_第3页
第3页 / 共48页
内存模型与多线程技术_第4页
第4页 / 共48页
内存模型与多线程技术_第5页
第5页 / 共48页
点击查看更多>>
资源描述

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

1、研究院java内存模型与多线程技术yangjsalibaba-研究院主要内容和目的学习java多线程理论基础:JMM(java内存模型)学习java多线程技术基础:理解同步是如和工作分析程序什么时候需要同步澄清对volatile误解,正确使用TaskCancellationandThreadShutdown策略LazyinitializationSafety技术研究院JMM(java内存模型)1.什么是Java内存模型2.Java内存模型相关概念3.java线程和内存交互行为定义4.Ordering&visibility5.JMM相关java语言规范研究院内存模型操作平台的内存模型寄存器,CP

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

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

4、ign和use,这些操作行为具有原子性,且相互依赖,有明确的调用先后顺序Auseaction(byathread)transfersthecontentsofthethreadsworkingcopyofavariabletothethreadsexecutionengine.Anassignaction(byathread)transfersavaluefromthethreadsexecutionengineintothethreadsworkingcopyofavariable.Areadaction(bythemainmemory)transmitsthecontentsofthema

5、stercopyofavariabletoathreadsworkingmemoryforusebyalaterloadoperation.Aload action(byathread)putsavaluetransmittedfrommainmemorybyareadactionintothethreadsworkingcopyofavariable.Astore action(byathread)transmitsthecontentsofthethreadsworkingcopyofavariabletomainmemoryforusebyalaterwriteoperation.Awr

6、iteaction(bythemainmemory)putsavaluetransmittedfromthethreadsworkingmemorybyastoreactionintothemastercopyofavariableinmainmemory.研究院java线程和内存交互分析例子分析:classSimple inta=1,b=2;/Thread1executes voidto() a=3;b=4; /Thread2executes voidfro()System.out.println(a=+a+,b=+b); 类似计算机多级存储器结构,WorkingMemory类似Cache机

7、制问题:变量a,b何时写会mainmemory?研究院Ordering&visibility 程序顺序:程序声明它们应当发生的顺序执行顺序:JMM不保证线程对变量操作发生的顺序和被其他线程看到的是同样的顺序。JMM容许线程以写入变量时所不相同的次序把变量存入主存线程内部本身遵循程序顺序,从线程外看到的是执行顺序编译器和处理器可能会为了性能优化,进行重新排序程序执行为了优化也可能重新排序研究院Ordering&visibility多线程场景分析classSimpleinta=1,b=2;/Thread1executesvoidto()a=3;/Thiscanappeartohappensecon

8、db=4;/Thiscanappeartohappenfirst/Thread2executesvoidfro()System.out.println(a=+a+,b=+b);下面哪种结果是正确的:a=1,b=2a=1,b=4a=3,b=2a=3,b=4研究院Happens-Before Memory Model类似释放一致性模型类似释放一致性模型Partialordering(happens-before):如果B能够看到A动作产生的结果,我们说Ahappens-beforeB,JMM定义了一些这样的规则,如:Program order rule.Eachactioninathreadhap

9、pens-beforeeveryactioninthatthreadthatcomeslaterintheprogramorder.Monitor lock rule.Anunlockonamonitorlockhappens-beforeeverysubsequentlockonthatsamemonitorlock.Volatile variable rule.Awritetoavolatilefieldhappens-beforeeverysubsequentreadofthatsamefield研究院The rules for happens-before 研究院JMM相关java语言

10、规范JMM定义了保证内存操作跨线程的正确的Ordering和visibility方法Java语言提供的技术和工具synchronized块volatile变量(在JDK5+的JVM中得到修补)工具类:java.util.concurrent.locks原子变量java.util.concurrent.atomicFinal变量(在JDK5+的JVM中得到修补)研究院正确的理解synchronized1.synchronized作用说明2.Synchronized内存模型语义分析3.如何判定多线程的程序何时需要Synchronized4.同步需求的JMM内存交互分析练习5.锁对象的引用在同步块中

11、发生修改会出现什么?6.HostspotJVM的synchronized优化技术7.直接使用synchronized不足之处研究院synchronized 作用说明Lowlevellocking什么时候需要synchronized?一个变量有可能被多个线程访问,其中至少有一个线程是写操作每个对象对象都有一个相关的lock对象(监视器)java语言没有提供分离的lock和unlock操作,但是在JVM提供了两个单独的指令monitorenter和monitorext来实现特性Atomicity:LockingtoobtainmutualexclusionVisibility:Ensuringth

12、atchangestoobjectfieldsmadeinonethreadareseeninotherthreads(memory)Ordering:EnsuringthatyouarentsurprisedbytheorderinwhichstatementsareexecutedBlocking:Cantinterrupt研究院Synchronized内存模型语义分析Synchronized:通过对象引用找到同步对象,然后获取对象上的监视器进行锁操作当线程进入synchronized块之后首先要做的是清洗threadsworkingmemory,对块内使用到的变量要么执行assign动作

13、要么对use的变量执行read-load原子操作从mainmemory装载新的值当线程退出synchronized块之前,对它在workingmemory中所有的assignedvalues执行storewrite原子操作,写回mainmemory研究院Synchronized内存模型语义分析Example: /block until obtain locksynchronized(obj)/get main memory value of field1 and field2intx=obj.field1;inty=obj.field2;obj.field3=x+y;/commit value

14、 of field3 to main memory/release lock研究院如何分析多线程并发需求classSynchSimpleinta=1,b=2;/Thread1executessynchronizedvoidto()a=3;b=4;/Thread2executesvoidfro()System.out.println(a=+a+,b=+b);以下哪种结果是正确的?a=1,b=2a=1,b=4a=3,b=2a=3,b=4这是一个线程安全的类吗?接下来我们通过JMM语义来分析这个例子研究院JMM内存交互分析研究院JMM内存交互分析SynchSimple分析:writea和writeb

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

16、究院问题?这个方法的同步块有可能被多个线程并发执行!这个方法的同步块有可能被多个线程并发执行!有可能在有可能在intArr.length size的条件下获得两把不同的锁的条件下获得两把不同的锁锁对象的引用在同步块中发生修改会出现什么?锁对象的引用在同步块中发生修改会出现什么?publicvoidfoo(intisze)synchronized(intArr)if(intArr.lengthsize)intnewIntArr=newintsize;System.arraycopy(intArr,0,newIntArr,0,intArr.length);intArr=newintArr;研究院直

17、接使用synchronized 不足之处和发展不能够扩越多个对象当在等待锁对象的时候不能中途放弃,直到成功等待没有超时限制Thread.interrupt()不能中断阻塞JDK5中提供更加灵活的机制:Lock和Conditionsynchronized在JDK6中性能将会有很大提升研究院Hostspot JVM的synchronized优化技术锁省略锁省略:锁对象的引用时线程本地对象(线程的堆栈内的对象)publicStringgetStoogeNames()Vectorv=newVector();v.add(Moe);v.add(Larry);v.add(Curly);returnv.toS

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

19、使用暂挂。研究院理解和使用理解和使用Volatile变量变量Volatile变量的内存模型分析变量的内存模型分析使用valatileJDK5的util.concurrent.atomic研究院Volatile变量的内存模型分析变量的内存模型分析“不要相信volatile”,这种说法已经过时旧的内存模型:保证读写volatile都直接发生在mainmemory中,线程的workingmemory不进行缓存仅仅保证这些volatile使用的价值和意义不大在新的内存模型下对volatile的语义进行了修补和增强如果当线程A写入volatile变量V而线程B读取V时,那么在写入V时,A可见的所有变量值

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

21、Volatile Guarantees VisibilityStop用volatile修饰来保证变量的写可见性classTaskimplementsRunnableprivatevolatilebooleanstop=false;publicvoidstop()stop=true;publicvoidrun()while(!stop)runTask();tryThread.sleep(100);privatevoidrunTask()/*.*/研究院Volatile Guarantees OrderingIf a thread reads data, there is a happens-be

22、fore 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变量比synchronization要便宜很多在jdk5中推荐采用util.concurrent.atomic工作机制类似Volatile同时提供了简单运算的原子行为研究院JDK5的u

23、til.concurrent.atomicget()具有读取volatile变量的内存效果。set()具有写入(分配)volatile变量的内存效果支持操作:getAndSetgetAndAddaddAndGetgetAndDecrementgetAndIncrementdecrementAndGetincrementAndGet只要你有足够的能力,用Atomic变量能够实现所有的同步研究院Cancellation and Shutdown1.CancellationandShutdown2.Taskcancellationpolicy设计3.Cancellationpolicy:Interr

24、uption4.正确处理InterruptedException研究院Cancellation and Shutdowncleanupanyworkthenterminate.(Safeterminate)为什么需要cancellable(中断正在进行的活动)User-requestedcancellationTime-limitedactivitiesApplicationeventsErrorsShutdown安全快速可靠结束一个线程是一个比较复杂的话题Java没有提供安全的强迫一个Thread结束的方法Javaprovidesinterruption,acooperativemechan

25、ism研究院cancellation policy 设计How:howothercodecanrequestcancellationWhen:whenthetaskcheckswhethercancellationhasbeenrequestedWhat:whatactionsthetasktakesinresponsetoacancellationrequest.研究院Example: cancellation policy 设计classTaskimplementsRunnableprivatevolatilebooleanstop=false;publicvoidstop()stop=t

26、rue;publicvoidrun()while(!stop)runTask();tryThread.sleep(100);privatevoidrunTask()/*.*/研究院Example: cancellation policy 设计分析How,When,How?问题:pollingloops,只有一个检查点线程不能立刻结束,要等到检测的时候遇到Blockingmethod有可能无法中止检查的变量必须是volatile修饰的研究院Cancellation policy :Interruption 礼貌地劝告另一个线程在它愿意并且方便的时候停止它正在做的事情。(Interruptioni

27、sacooperativemechanism)Thread中断状态(interruptedstatus):线程的一个内部属性,类型:boolean,初始值:false.Thread.interrupt():设置interruptedstatus为true研究院interruption Policy 分析分析:How:Thread.interrupt()方法.interrupt()只是设置线程的中断状态。表示当前线程应该停止运行。When:在Thread.sleep()、Thread.join()或Object.wait()等方法中取消阻塞并抛出InterruptedException,也可以程

28、序检测:轮询中断状态:Thread.isInterrupted()读取并清除:Thread.interrupted()InterruptibleChannel(java.nio):MoststandardChannelsimplementInterruptibleChannel等待获取文件锁定时可以被另一个线程中断研究院Cancellation policy :InterruptionInterruptionisusuallythemostsensiblewaytoimplementcancellation其他问题不能打断一些IO操作,比如文件操作无法终止在synchronized块上锁住的T

29、hreadSynchronoussocketI/Oinjava.io研究院InterruptedException 检查型异常:检查型异常:java.lang.InterruptedException 当线程在很长一段时间内一直处于正在等待、休眠或暂停状态(Object.wait(),Object.wait(long),Object.wait(long,int),Thread.sleep(long)),而另一个线程用Thread类中的interrupt方法中断它时,抛出该异常。阻塞(阻塞(blocking)方法方法方法签名包括抛出InterruptedException,调用一个阻塞方法则意味

30、着这个方法也是一个阻塞方法当中断阻塞方法时,抛出当中断阻塞方法时,抛出InterruptedExceptionThread在Thread.sleep()和Object.wait()等方法中支持的取消机制,表明可以提前返回。当一个阻塞方法检测到中断并抛出InterruptedException时,它清除中断状态研究院如何处理InterruptedException错误的做法:swallowinterruptionrequeststry Task task = queue.take(); task.execute(); catch (InterruptedException e) log.erro

31、r(); 研究院如何处理InterruptedExceptionRestoretheinterrupt如果真的要湮灭InterruptedException,应该保留被别人中断的证据,交给高层去决定。/恰当的做法: try Task task = queue.take(); task.execute(); catch (InterruptedException e) log.error(); Thread.currentThread().interrupt(); PropagatetheInterruptedException重新抛出它,如果抛到顶层,可以结束当前线程研究院Double-Che

32、cked Locking目的:在多线程应用中用来lazyinitialization并保证Singlen在java语言中DCL不成立/Brokenmultithreadedversion/Double-CheckedLockingidiomclassFooprivateHelperhelper=null;publicHelpergetHelper()if(helper=null)synchronized(this)if(helper=null)helper=newHelper();returnhelper;/otherfunctionsandmembers.研究院为什么在java语言中DCL不

33、成立 Java构造对象不是原子操作:1.先申请一块空内存2.将其地址赋予对象引用3.在对象引用所指的地址之上构建对象,调用构造函数初始化很多人提供了很多方法来修复DCL,但是没有人能够成功行为正确的程序,但是增加了同步的负担/Correctmultithreadedversion,butsynchronizedeverytime!classFooprivateHelperhelper=null;publicsynchronizedHelpergetHelper()if(helper=null)helper=newHelper();returnhelper;/otherfunctionsandm

34、embers.研究院Initialize-On-Demand Holder Class idiomprivatestaticclassLazySomethingHolderpublicstaticSomethingsomething=newSomething();.publicstaticSomethinggetInstance()returnLazySomethingHolder.something;研究院几点建议开发多线程系统一定要理解java的内存模型,那样你才能够正确地分析线程需求尽量使用现成的解决方案,util.concurrent优化的前提是保证程序的正确性,其次才是提高程序的性能缩小锁的作用范围缩短锁的存在时间

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号