Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
JavaÄÚ´æÄ£ÐÍJMMdzÎö
 
À´Ô´£ºÀ´×ÔÍøÂç ·¢²¼ÓÚ£º 2017-5-31
  2881  次浏览      29
 

JMM¼ò½é

Java Memory Model¼ò³ÆJMM, ÊÇһϵÁеÄJavaÐéÄâ»úƽ̨¶Ô¿ª·¢ÕßÌṩµÄ¶àÏ̻߳·¾³ÏµÄÄÚ´æ¿É¼ûÐÔ¡¢ÊÇ·ñ¿ÉÒÔÖØÅÅÐòµÈÎÊÌâµÄÎ޹ؾßÌåÆ½Ì¨µÄͳһµÄ±£Ö¤¡£(¿ÉÄÜÔÚÊõÓïÉÏÓëJavaÔËÐÐʱÄÚ´æ·Ö²¼ÓÐÆçÒ壬ºóÕßÖ¸¶Ñ¡¢·½·¨Çø¡¢Ïß³ÌÕ»µÈÄÚ´æÇøÓò)¡£

²¢·¢±à³ÌÓжàÖÖ·ç¸ñ£¬³ýÁËCSP(ͨÐÅ˳Ðò½ø³Ì)¡¢ActorµÈÄ£ÐÍÍ⣬´ó¼Ò×îÊìϤµÄÓ¦¸ÃÊÇ»ùÓÚÏ̺߳ÍËøµÄ¹²ÏíÄÚ´æÄ£ÐÍÁË¡£ÔÚ¶àÏ̱߳à³ÌÖУ¬ÐèҪעÒâÈýÀಢ·¢ÎÊÌâ:

1.Ô­×ÓÐÔ

2.¿É¼ûÐÔ

3.ÖØÅÅÐò

Ô­×ÓÐÔÉæ¼°µ½£¬Ò»¸öÏß³ÌÖ´ÐÐÒ»¸ö¸´ºÏ²Ù×÷µÄʱºò£¬ÆäËûÏß³ÌÊÇ·ñÄܹ»¿´µ½ÖмäµÄ״̬¡¢»ò½øÐиÉÈÅ¡£µäÐ͵ľÍÊÇi++µÄÎÊÌâÁË£¬Á½¸öÏß³Ìͬʱ¶Ô¹²ÏíµÄ¶ÑÄÚ´æÖ´ÐÐ++²Ù×÷£¬¶ø++²Ù×÷ÔÚJVM¡¢ÔËÐÐʱ¡¢CPUÖеÄʵÏÖ¶¼¿ÉÄÜÊÇÒ»¸ö¸´ºÏ²Ù×÷, ÀýÈçÔÚJVMÖ¸ÁîµÄ½Ç¶ÈÀ´¿´Êǽ«iµÄÖµ´Ó¶ÑÄÚ´æ¶Áµ½²Ù×÷ÊýÕ»¡¢¼ÓÉÏÒ»¡¢ÔÙд»Øµ½¶ÑÄÚ´æµÄi£¬Õ⼸¸ö²Ù×÷µÄÆÚ¼ä£¬Èç¹ûûÓÐÕýÈ·µÄͬ²½£¬ÆäËûÏß³ÌÒ²¿ÉÒÔͬʱִÐУ¬¿ÉÄܵ¼ÖÂÊý¾Ý¶ªÊ§µÈÎÊÌâ¡£³£¼ûµÄÔ­×ÓÐÔÎÊÌâÓֽоºÌ«Ìõ¼þ£¬ÊÇ»ùÓÚÒ»¸ö¿ÉÄÜʧЧµÄ½á¹û½øÐÐÅжϣ¬Èç¶ÁÈ¡-ÐÞ¸Ä-дÈë¡£ ¿É¼ûÐÔºÍÖØÅÅÐòÎÊÌâ¶¼Ô´ÓÚϵͳµÄÓÅ»¯¡£

¼òµ¥ËµÖØÅÅÐò¾ÍÊdzÌÐòʵ¼ÊÖ´ÐеÄ˳ÐòºÍ³ÌÐòÖеÄ˳Ðò²»Ò»Ö¡£

ÓÉÓÚCPUµÄÖ´ÐÐËٶȺÍÄÚ´æµÄ´æÈ¡ËÙ¶ÈÑÏÖØ²»Æ¥Å䣬ΪÁËÓÅ»¯ÐÔÄÜ£¬»ùÓÚʱ¼ä¾Ö²¿ÐÔ¡¢¿Õ¼ä¾Ö²¿ÐԵȾֲ¿ÐÔÔ­Àí£¬CPUÔÚºÍÄÚ´æ¼äÔö¼ÓÁ˶à²ã¸ßËÙ»º´æ£¬µ±ÐèҪȡÊý¾Ýʱ£¬CPU»áÏȵ½¸ßËÙ»º´æÖвéÕÒ¶ÔÓ¦µÄ»º´æÊÇ·ñ´æÔÚ£¬´æÔÚÔòÖ±½Ó·µ»Ø£¬Èç¹û²»´æÔÚÔòµ½ÄÚ´æÖÐÈ¡³ö²¢±£´æÔÚ¸ßËÙ»º´æÖС£ÏÖÔÚ¶àºË´¦ÀíÆ÷Ô½»ù±¾ÒѾ­³ÉΪ±êÅ䣬Õâʱÿ¸ö´¦ÀíÆ÷¶¼ÓÐ×Ô¼ºµÄ»º´æ£¬Õâ¾ÍÉæ¼°µ½ÁË»º´æÒ»ÖÂÐÔµÄÎÊÌ⣬CPUÓв»Í¬Ç¿ÈõµÄÒ»ÖÂÐÔÄ£ÐÍ£¬×îÇ¿µÄÒ»ÖÂÐÔ°²È«ÐÔ×î¸ß£¬Ò²·ûºÏÎÒÃǵÄ˳Ðò˼¿¼µÄģʽ£¬µ«ÊÇÔÚÐÔÄÜÉÏÒòΪÐèÒª²»Í¬CPUÖ®¼äµÄЭµ÷ͨОͻáÓкܶ࿪Ïú

µäÐ͵ÄCPU»º´æ½á¹¹Ê¾ÒâͼÈçÏÂ

CPUµÄÖ¸ÁîÖÜÆÚͨ³£ÎªÈ¡Ö¸Áî¡¢½âÎöÖ¸Áî¶ÁÈ¡Êý¾Ý¡¢Ö´ÐÐÖ¸Áî¡¢Êý¾Ýд»Ø¼Ä´æÆ÷»òÄÚ´æ¡£´®ÐÐÖ´ÐÐÖ¸ÁîʱÆäÖеĶÁÈ¡´æ´¢Êý¾Ý²¿·ÖÕ¼ÓÃʱ¼ä½Ï³¤£¬ËùÒÔCPUÆÕ±é²ÉȡָÁîÁ÷Ë®Ïߵķ½Ê½Í¬Ê±Ö´Ðжà¸öÖ¸Áî, Ìá¸ßÕûÌåÍÌÍÂÂÊ£¬¾ÍÏñ¹¤³§Á÷Ë®ÏßÒ»Ñù¡£

¶ÁÈ¡Êý¾ÝºÍд»ØÊý¾Ýµ½ÄÚ´æÏà±ÈÖ´ÐÐÖ¸ÁîµÄËٶȲ»ÔÚÒ»¸öÊýÁ¿¼¶ÉÏ£¬ËùÒÔCPUʹÓüĴæÆ÷¡¢¸ßËÙ»º´æ×÷Ϊ»º´æºÍ»º³å£¬ÔÚ´ÓÄÚ´æÖжÁÈ¡Êý¾Ýʱ£¬»á¶Áȡһ¸ö»º´æÐÐ(cache line)µÄÊý¾Ý£¨ÀàËÆ´ÅÅ̶ÁÈ¡¶Áȡһ¸öblock£©¡£Êý¾Ýд»ØµÄÄ£¿éÔÚ¾ÉÊý¾ÝûÓÐÔÚ»º´æÖеÄÇé¿öÏ»Ὣ´æ´¢ÇëÇó·ÅÈëÒ»¸östore bufferÖмÌÐøÖ´ÐÐÖ¸ÁîÖÜÆÚµÄÏÂÒ»¸ö½×¶Î£¬Èç¹û´æÔÚÓÚ»º´æÖÐÔò»á¸üлº´æ£¬»º´æÖеÄÊý¾Ý»á¸ù¾ÝÒ»¶¨²ßÂÔflushµ½ÄÚ´æ¡£


public class MemoryModel {
private int count;
private boolean stop;
public void initCountAndStop() {
count = 1;
stop = false;
}
public void doLoop() {
while(!stop) {
count++;
}
}
public void printResult() {
System.out.println(count);
System.out.println(stop);
}
}

ÉÏÃæÕâ¶Î´úÂëÖ´ÐÐʱÎÒÃÇ¿ÉÄÜÈÏΪcount = 1»áÔÚstop = falseǰִÐÐÍê³É£¬ÕâÔÚÉÏÃæµÄCPUÖ´ÐÐͼÖÐÏÔʾµÄÀíÏë״̬ÏÂÊÇÕýÈ·µÄ£¬µ«ÊÇÒª¿¼ÂÇÉϼĴæÆ÷¡¢»º´æ»º³åµÄʱºò¾Í²»ÕýÈ·ÁË, ÀýÈçstop±¾ÉíÔÚ»º´æÖе«ÊÇcount²»ÔÚ£¬Ôò¿ÉÄÜstop¸üкóÔÙcountµÄwrite bufferд»ØÖ®Ç°Ë¢Ðµ½ÁËÄÚ´æ¡£

ÁíÍâCPU¡¢±àÒëÆ÷£¨¶ÔÓÚJavaÒ»°ãÖ¸JIT£©¶¼¿ÉÄÜ»áÐÞ¸ÄÖ¸ÁîÖ´ÐÐ˳Ðò£¬ÀýÈçÉÏÊö´úÂëÖÐcount = 1ºÍstop = falseÁ½Õß²¢Ã»ÓÐÒÀÀµ¹ØÏµ£¬ËùÒÔCPU¡¢±àÒëÆ÷¶¼ÓпÉÄÜÐÞ¸ÄÕâÁ½ÕßµÄ˳Ðò£¬¶øÔÚµ¥Ïß³ÌÖ´ÐеijÌÐò¿´À´½á¹ûÊÇÒ»ÑùµÄ£¬ÕâÒ²ÊÇCPU¡¢±àÒëÆ÷Òª±£Ö¤µÄas-if-sequantial(²»¹ÜÈçºÎÐÞ¸ÄÖ´ÐÐ˳Ðò£¬µ¥Ï̵߳ÄÖ´Ðнá¹û²»±ä)¡£ÓÉÓںܴ󲿷ֳÌÐòÖ´Ðж¼Êǵ¥Ï̵߳ģ¬ËùÒÔÕâÑùµÄÓÅ»¯ÊÇ¿ÉÒÔ½ÓÊܲ¢ÇÒ´øÀ´Á˽ϴóµÄÐÔÄÜÌáÉý¡£µ«ÊÇÔÚ¶àÏ̵߳ÄÇé¿öÏ£¬Èç¹ûûÓнøÐбØÒªµÄͬ²½²Ù×÷Ôò¿ÉÄÜ»á³öÏÖÁîÈËÒâÏë²»µ½µÄ½á¹û¡£ÀýÈçÔÚÏß³ÌT1Ö´ÐÐÍêinitCountAndStop·½·¨ºó£¬Ïß³ÌT2Ö´ÐÐprintResult£¬µÃµ½µÄ¿ÉÄÜÊÇ0, false, ¿ÉÄÜÊÇ1, false, Ò²¿ÉÄÜÊÇ0, true¡£Èç¹ûÏß³ÌT1ÏÈÖ´ÐÐdoLoop()£¬Ïß³ÌT2Ò»ÃëºóÖ´ÐÐinitCountAndStop, ÔòT1¿ÉÄÜ»áÌø³öÑ­»·¡¢Ò²¿ÉÄÜÓÉÓÚ±àÒëÆ÷µÄÓÅ»¯ÓÀÔ¶ÎÞ·¨¿´µ½stopµÄÐ޸ġ£

ÓÉÓÚÉÏÊöÕâЩ¶àÏß³ÌÇé¿öϵĸ÷ÖÖÎÊÌ⣬¶àÏß³ÌÖеijÌÐò˳ÐòÒѾ­²»Êǵײã»úÖÆÖеÄÖ´ÐÐ˳ÐòºÍ½á¹û£¬±à³ÌÓïÑÔÐèÒª¸ø¿ª·¢ÕßÒ»ÖÖ±£Ö¤£¬Õâ¸ö±£Ö¤¼òµ¥À´Ëµ¾ÍÊÇÒ»¸öÏ̵߳ÄÐ޸ĺÎʱ¶ÔÆäËûÏ߳̿ɼû£¬Òò´ËJavaÓïÑÔÌá³öÁËJavaMemoryModel¼´JavaÄÚ´æÄ£ÐÍ£¬¶ÔÓÚJavaÓïÑÔ¡¢JVM¡¢±àÒëÆ÷µÈʵÏÖÕßÐèÒª°´ÕÕÕâ¸öÄ£Ð͵ÄÔ¼¶¨À´½øÐÐʵÏÖ¡£JavaÌṩÁËvolatile¡¢synchronized¡¢finalµÈ»úÖÆÀ´°ïÖú¿ª·¢Õß±£Ö¤¶àÏ̳߳ÌÐòÔÚËùÓд¦ÀíÆ÷ƽ̨ÉϵÄÕýÈ·ÐÔ¡£

ÔÚJDK1.5֮ǰ£¬JavaµÄÄÚ´æÄ£ÐÍÓÐ×ÅÑÏÖØµÄÎÊÌ⣬ÀýÈçÔھɵÄÄÚ´æÄ£ÐÍÖУ¬Ò»¸öÏ߳̿ÉÄÜÔÚ¹¹ÔìÆ÷Ö´ÐÐÍê³Éºó¿´µ½Ò»¸öfinal×ֶεÄĬÈÏÖµ¡¢volatile×ֶεÄдÈë¿ÉÄÜ»áºÍ·Çvolatile×ֶεĶÁÐ´ÖØÅÅÐò¡£

ËùÒÔÔÚJDK1.5ÖУ¬Í¨¹ýJSR133Ìá³öÁËеÄÄÚ´æÄ£ÐÍ£¬ÐÞ¸´Ö®Ç°³öÏÖµÄÎÊÌâ¡£

ÖØÅÅÐò¹æÔò

volatileºÍ¼àÊÓÆ÷Ëø

ÆäÖÐÆÕͨ¶ÁÖ¸getfield, getstatic, ·ÇvolatileÊý×éµÄ arrayload , ÆÕͨдָ putfield , putstatic, ·ÇvolatileÊý×éµÄ arraystore ¡£

volatile¶Áд·Ö±ðÊÇvolatile×Ö¶ÎµÄ getfield, getstatic ºÍ putfield, putstatic¡£

monitorenterÊǽøÈëͬ²½¿é»òͬ²½·½·¨, monitorexist Ö¸Í˳öͬ²½¿é»òͬ²½·½·¨¡£

ÉÏÊö±í¸ñÖеÄNoÖ¸ÏȺóÁ½¸ö²Ù×÷²»ÔÊÐíÖØÅÅÐò£¬Èç(ÆÕͨд, volatileд)Ö¸·Çvolatile×ֶεÄдÈë²»ÄܺÍÖ®ºóÈÎÒâµÄvolatile×ֶεÄдÈëÖØÅÅÐò¡£µ±Ã»ÓÐNoʱ£¬ËµÃ÷ÖØÅÅÐòÊÇÔÊÐíµÄ£¬µ«ÊÇJVMÐèÒª±£Ö¤×îС°²È«ÐÔ-¶ÁÈ¡µÄֵҪôÊÇĬÈÏÖµ£¬ÒªÃ´ÊÇÆäËûÏß³ÌдÈëµÄ£¨64λµÄdoubleºÍlong¶Áд²Ù×÷ÊǸöÌØÀý£¬µ±Ã»ÓÐvolatileÐÞÊÎʱ£¬²¢²»Äܱ£Ö¤¶ÁдÊÇÔ­×ӵ쬵ײã¿ÉÄܽ«Æä²ð·ÖΪÁ½¸öµ¥¶ÀµÄ²Ù×÷£©¡£

final×Ö¶Î

final×Ö¶ÎÓÐÁ½¸ö¶îÍâµÄÌØÊâ¹æÔò

final×ֶεÄдÈ루ÔÚ¹¹ÔìÆ÷ÖнøÐУ©ÒÔ¼°final×ֶζÔÏó±¾ÉíµÄÒýÓõÄдÈë¶¼²»ÄܺͺóÐøµÄ£¨¹¹ÔìÆ÷ÍâµÄ£©³ÖÓиÃfinal×ֶεĶÔÏóµÄдÈëÖØÅÅÐò¡£ÀýÈç, ÏÂÃæµÄÓï¾äÊDz»ÄÜÖØÅÅÐòµÄ

x.finalField = v; ...; sharedRef = x;

final×ֶεĵÚÒ»´Î¼ÓÔØ²»ÄܺͳÖÓÐÕâ¸öfinal×ֶεĶÔÏóµÄдÈëÖØÅÅÐò£¬ÀýÈçÏÂÃæµÄÓï¾äÊDz»ÔÊÐíÖØÅÅÐòµÄ

x = sharedRef; ...; i = x.finalFiel

ÄÚ´æÆÁÕÏ

´¦ÀíÆ÷¶¼Ö§³ÖÒ»¶¨µÄÄÚ´æÆÁÕÏ(memory barrier)»òÕ¤À¸(fence)À´¿ØÖÆÖØÅÅÐòºÍÊý¾ÝÔÚ²»Í¬µÄ´¦ÀíÆ÷¼äµÄ¿É¼ûÐÔ¡£½«CPUºÍÄÚ´æ¼äµÄÊý¾Ý´æÈ¡²Ù×÷·ÖΪloadºÍstore¡£ÀýÈ磬CPU½«Êý¾Ýд»ØÊ±£¬»á½«storeÇëÇó·ÅÈëwrite bufferÖеȴýflushµ½Äڴ棬¿ÉÒÔͨ¹ý²åÈëbarrierµÄ·½Ê½·ÀÖ¹Õâ¸östoreÇëÇóÓëÆäËûµÄÇëÇóÖØÅÅÐò¡¢±£Ö¤Êý¾ÝµÄ¿É¼ûÐÔ¡£¿ÉÒÔÓÃÒ»¸öÉú»îÖеÄÀý×ÓÀà±ÈÆÁÕÏ£¬ÀýÈç×øµØÌúµÄбÆÂʽµçÌÝʱ£¬´ó¼Ò°´Ë³Ðò½øÈëµçÌÝ£¬µ«ÊÇ»áÓÐһЩÈË´Ó×ó²àÈÆ¹ýÈ¥£¬ÕâÑù³öµçÌÝʱ˳Ðò¾Í²»ÏàͬÁË£¬Èç¹ûÓÐÒ»¸öÈËЯ´øÁËÒ»¸ö´óµÄÐÐÀî¶ÂסÁË£¨ÆÁÕÏ£©£¬ÔòºóÃæµÄÈ˾Ͳ»ÄÜÈÆ¹ýÈ¥ÁË:)¡£ÁíÍâÕâÀïµÄbarrierºÍGCÖÐÓõ½µÄwrite barrierÊDz»Í¬µÄ¸ÅÄî¡£

ÄÚ´æÆÁÕϵķÖÀà

¼¸ºõËùÓеĴ¦ÀíÆ÷¶¼Ö§³ÖÒ»¶¨´ÖÁ£¶ÈµÄbarrierÖ¸Áͨ³£½Ð×öFence(Õ¤À¸¡¢Î§Ç½)£¬Äܹ»±£Ö¤ÔÚfence֮ǰ·¢ÆðµÄloadºÍstoreÖ¸Áî¶¼ÄÜÑϸñµÄºÍfenceÖ®ºóµÄloadºÍstore±£³ÖÓÐÐò¡£Í¨³£°´ÕÕÓÃ;»á·ÖΪÏÂÃæËÄÖÖbarrier

LoadLoad Barriers

Load1; LoadLoad; Load2;

±£Ö¤Load1µÄÊý¾ÝÔÚLoad2¼°Ö®ºóµÄloadǰ¼ÓÔØ

StoreStore Barriers

Store1; StoreStore; Store2

±£Ö¤Store1µÄÊý¾ÝÏÈÓÚStore2¼°Ö®ºóµÄÊý¾Ý ÔÚÆäËû´¦ÀíÆ÷¿É¼û

LoadStore Barriers

Load1; LoadStore; Store2

±£Ö¤Load1µÄÊý¾ÝµÄ¼ÓÔØÔÚStore2ºÍÖ®ºóStoreµÄÊý¾Ýflushǰ

StoreLoad Barriers

Store1; StoreLoad; Load2

±£Ö¤Store1µÄÊý¾ÝÔÚÆäËû´¦ÀíÆ÷ǰ¿É¼û(Èçflushµ½ÄÚ´æ)ÏÈÓÚLoad2ºÍÖ®ºóµÄloadµÄÊý¾ÝµÄ¼ÓÔØ¡£StoreLoad BarrierÄܹ»·ÀÖ¹load¶ÁÈ¡µ½Store1µÄ¾ÉÊý¾Ý¶ø²»ÊÇ×î½üÆäËû´¦ÀíÆ÷дÈëµÄÊý¾Ý£¬ÀýÈçStore1µÄдÈëÔÚWrite BufferÖÐ, Load2¿ÉÄÜÖ±½Ó´ÓWrite BufferÖжÁÈ¡ÁËStore1µÄÖµ¶ø²»ÊÇÆäËû´¦ÀíÆ÷ÖпÉÄܵÄ×îÐÂÖµ¡£

¼¸ºõ½ü´úµÄËùÓеĶദÀíÆ÷¶¼ÐèÒªStoreLoad£¬StoreLoadµÄ¿ªÏúͨ³£ÊÇ×î´óµÄ£¬²¢ÇÒStoreLoad¾ßÓÐÆäËûÈýÖÖÆÁÕϵÄЧ¹û£¬ËùÒÔStoreLoad¿ÉÒÔµ±×öÒ»¸öͨÓõÄ(µ«ÊǸü¸ß¿ªÏúµÄ)ÆÁÕÏ¡£

ËùÒÔ£¬ÀûÓÃÉÏÊöµÄÄÚ´æÆÁÕÏ£¬¿ÉÒÔʵÏÖÉÏÃæ±í¸ñÖеÄÖØÅÅÐò¹æÔò

ΪÁËÖ§³Öfinal×ֶεĹæÔò£¬ÐèÒª¶ÔfinalµÄдÈëÔö¼Ó barrier

x.finalField = v; StoreStore; sharedRef = x;

²åÈëÄÚ´æÆÁÕÏ

µ¥´¦ÀíÆ÷ÉÏÓÉÓڻᱣ֤͸Ã÷µÄ˳ÐòÒ»ÖÂÐÔ£¬ËùÒÔ²¢²»ÐèÒªÃ÷È·µÄ²åÈëÄÚ´æÆÁÕÏ¡£

ÔÚ¶à´¦ÀíÆ÷Çé¿öÏ£¬»ùÓÚÉÏÃæµÄ¹æÔò£¬¿ÉÒÔÔÚvolatile×ֶΡ¢synchronized¹Ø¼ü×ֵĴ¦ÀíÉÏÔö¼ÓÆÁÕÏÀ´Âú×ãÄÚ´æÄ£Ð͵ĹæÔò¡£

×î±£ÊØµÄ²ßÂÔÊÇÔÚvolatileµÄǰºó¶¼¼ÓÉÏËùÓÐµÄÆÁÕÏ£¬µ«ÊÇÕâÑùÔÚ´ó¶àÊýÇé¿ö¶¼ÊDz»±ØÒªÇÒÖØ¸´µÄ£¬ËùÒÔÔÙÒÔvolatile×Ö¶Îͨ³£¶Á¶àдÉٵļÙÉ裬¿ÉÒԵóöÒÔÏÂÒ»ÖÖ²ßÂÔ¹©±àÒëÆ÷¿ª·¢Õ߲ο¼:

volatile storeǰ²åÈëLoadStore;StoreStoreÆÁÕÏ

ËùÓÐfinal×Ö¶ÎдÈëºóµ«ÔÚ¹¹ÔìÆ÷·µ»ØÇ°²åÈëStoreStore

volatile storeºó²åÈëStoreLoadÆÁÕÏ

ÔÚvolatile loadºó²åÈëLoadLoadºÍLoadStoreÆÁÕÏ

monitor enterºÍvolatile load¹æÔòÒ»Ö£¬monitor exit ºÍvolatile store¹æÔòÒ»Ö¡£

x86/64´¦ÀíÆ÷

x86´¦ÀíÆ÷¼Ü¹¹Ï£¬Ö»ÐèÒª²åÈëStoreLoadÆÁÕÏ, ÁíÍâJDK9ÖÖµÄUnsafeÀàÌṩÁËеÄloadFence¡¢storeFenceºÍfullFence·½·¨¡£

¿ÉÒÔ¿´ÏÂopenjdk9ÖеÄtemplateTable_x86.cppºÍassembler_x86.hpp¡£

x86ÖÐͨ¹ýlock; addl $0,0(%%esp)ÕâÑùµÄ¿Õ²Ù×÷À´ÊµÏÖStoreLoad

templateTable_x86.cpp
void TemplateTable::volatile_barrie

r(Assembler::Membar_mask_bits

order_constraint ) {
// Helper function to insert a

is-volatile test and memory barrier
if(!os::is_MP()) return; // Not

needed on single CPU
__ membar(order_constraint);
}
assembler_x86.hpp
// Serializes memory and blows

flags
void membar(Membar_mask_bits

order_constraint) {
if (os::is_MP()) {
// We only have to handle StoreLoad
if (order_constraint & StoreLoad) {
// All usable chips support "locked"

instructions which suffice
// as barriers, and are much faster

than the alternative of
// using cpuid instruction. We use

here a locked add [esp-C],0.
// This is conveniently otherwise

a no-op except for blowing
// flags, and introducing a false

dependency on target memory
// location. We can't do anything

with flags, but we can avoid
// memory dependencies in the

current method by locked-adding
// somewhere else on the stack.

Doing [esp+C] will collide with
// something on stack in curren

t method, hence we go for [esp-C].
// It is convenient since it is

almost always in data cache, for
// any small C. We need to step

back from SP to avoid data
// dependencies with other things

on below SP (callee-saves, for
// example). Without a clear way

to figure out the minimal safe
// distance from SP, it makes

sense to step back the complete
// cache line, as this will also

avoid possible second-order effects
// with locked ops against the c

ache line. Our choice of offset
// is bounded by x86 operand

encoding, which should stay within
// [-128; +127] to have the 8

-byte displacement encoding.
//
// Any change to this code may

need to revisit other places in
// the code where this idiom

is used, in particular the
// orderAccess code.
int offset = -VM_Version:

:L1_line_size();
if (offset < -128) {
offset = -128;
}
lock(); lockǰ׺
addl(Address(rsp, offset), 0);//

Assert the lock# signal here

addl $0,0(%%esp)
}
}
}
orderAccess_linux_x86.inline.hpp
// Compiler version last used for

testing: gcc 4.8.2
// Please update this information

when this file changes
// Implementation of class OrderAccess.
// A compiler barrier, forcing the

C++ compiler to invalidate all

memory assumptions
static inline void compiler_barrier() {
__asm__ volatile ("" : : : "memory");
}
inline void OrderAccess::loadload()

{ compiler_barrier(); }
inline void OrderAccess::storestore()

{ compiler_barrier(); }
inline void OrderAccess::loadstore()

{ compiler_barrier(); }
inline void OrderAccess::storeload(

) { fence(); }
inline void OrderAccess::acquire()

{ compiler_barrier(); }
inline void OrderAccess::release()

{ compiler_barrier(); }
inline void OrderAccess::fence() {
if (os::is_MP()) {
// always use locked addl since

mfence is sometimes expensive
#ifdef AMD64
__asm__ volatile ("lock; addl $0,0

(%%rsp)" : : : "cc", "memory");
#else
__asm__ volatile ("lock; addl $0,0

(%%esp)" : : : "cc", "memory");
#endif
}
compiler_barrier();
}

Happens-Before

Ç°ÃæÌáµ½µÄ¸÷ÖÖÄÚ´æÆÁÕ϶ÔÓ¦¿ª·¢ÕßÀ´Ëµ»¹ÊDZȽϸ´Ôӵײ㣬Òò´ËJMMÓÖ¿ÉÒÔʹÓÃһϵÁÐHappens-BeforeµÄÆ«Ðò¹ØÏµµÄ¹æÔò·½Ê½À´ËµÃ÷£¬ÒªÏë±£Ö¤Ö´ÐвÙ×÷BµÄÏ߳̿´µ½²Ù×÷AµÄ½á¹û£¨ÎÞÂÛAºÍBÊÇ·ñÔÚͬһ¸öÏß³ÌÖÐÖ´ÐÐ), ÄÇôÔÚAºÍBÖ®¼ä±ØÐëÒªÂú×ãHappens-Before¹ØÏµ£¬·ñÔòJVM¿ÉÒÔ¶ÔËüÃÇÈÎÒâÖØÅÅÐò¡£

Two actions can be ordered by a happens-before
 relationship. If one action happens-before
 another, then the first is visible to
 and ordered before the second.

Happens-Before¹æÔòÁбí

HappendBefore¹æÔò°üÀ¨

1.³ÌÐò˳Ðò¹æÔò: Èç¹û³ÌÐòÖвÙ×÷AÔÚ²Ù×÷B֮ǰ£¬ÄÇôͬһ¸öÏß³ÌÖвÙ×÷A½«ÔÚ²Ù×÷B֮ǰ½øÐÐ

2.¼àÊÓÆ÷Ëø¹æÔò: ÔÚ¼àÊÓÆ÷ËøÉϵÄËø²Ù×÷±ØÐëÔÚͬһ¸ö¼àÊÓÆ÷ËøÉϵļÓËø²Ù×÷֮ǰִÐÐ

3.volatile±äÁ¿¹æÔò: volatile±äÁ¿µÄдÈë²Ù×÷±ØÐëÔڸñäÁ¿µÄ¶Á²Ù×÷֮ǰִÐÐ

4.Ïß³ÌÆô¶¯¹æÔò: ÔÚÏß³ÌÉ϶ÔThread.startµÄµ÷ÓñØÐëÔÚ¸ÃÏß³ÌÖÐÖ´ÐÐÈκβÙ×÷֮ǰִÐÐ

5.Ï߳̽áÊø¹æÔò: Ïß³ÌÖеÄÈκβÙ×÷¶¼±ØÐëÔÚÆäËûÏ̼߳ì²âµ½¸ÃÏß³ÌÒѾ­½áÊøÖ®Ç°Ö´ÐÐ

6.ÖжϹæÔò: µ±Ò»¸öÏß³ÌÔÚÁíÒ»¸öÏß³ÌÉϵ÷ÓÃinterruptʱ£¬±ØÐëÔÚ±»ÖжÏÏ̼߳ì²âµ½interrupt֮ǰִÐÐ

7.´«µÝÐÔ: Èç¹û²Ù×÷AÔÚ²Ù×÷B֮ǰִÐУ¬²¢ÇÒ²Ù×÷BÔÚ²Ù×÷C֮ǰִÐУ¬ÄÇô²Ù×÷AÔÚ²Ù×÷C֮ǰִÐС£

ÆäÖÐÏÔÊ¾ËøÓë¼àÊÓÆ÷ËøÓÐÏàͬµÄÄÚ´æÓïÒ壬ԭ×Ó±äÁ¿ÓëvolatileÓÐÏàͬµÄÄÚ´æÓïÒå¡£ËøµÄ»ñÈ¡ºÍÊÍ·Å¡¢volatile±äÁ¿µÄ¶ÁÈ¡ºÍдÈë²Ù×÷Âú×ãÈ«Ðò¹ØÏµ£¬ËùÒÔ¿ÉÒÔʹÓÃvolatileµÄдÈëÔÚºóÐøµÄvolatileµÄ¶Áȡ֮ǰ½øÐС£

¿ÉÒÔÀûÓÃÉÏÊöHappens-BeforeµÄ¶à¸ö¹æÔò½øÐÐ×éºÏ¡£

ÀýÈçÏß³ÌA½øÈë¼àÊÓÆ÷Ëøºó£¬ÔÚÊͷżàÊÓÆ÷ËøÖ®Ç°µÄ²Ù×÷¸ù¾Ý³ÌÐò˳Ðò¹æÔòHappens-BeforeÓÚ¼àÊÓÆ÷ÊͷŲÙ×÷£¬¶ø¼àÊÓÆ÷ÊͷŲÙ×÷Happens-BeforeÓÚºóÐøµÄÏß³ÌBµÄ¶ÔÏàͬ¼àÊÓÆ÷ËøµÄ»ñÈ¡²Ù×÷£¬»ñÈ¡²Ù×÷Happens-BeforeÓëÏß³ÌBÖеIJÙ×÷¡£

×ܽá

ÉÏÃæËµÁËÄÇô¶à£¬Èç¹ûÒªÓü¸¾ä»°×ܽáµÄ»°£º

1.JMMÊÇJava³ÌÐò¶ÔÏß³ÌÈçºÎ½»»¥µÄͳһµÄÔ¼¶¨Ð­Òé

2.Happens-Before ˳Ðò: ±£Ö¤ÁËÒ»¸öÏ̵߳IJÙ×÷½á¹ûÄܹ»¶ÔÁíÒ»¸öÏ߳̿ɼû

3.synchronized¹Ø¼ü×ÖÌṩ»¥³âÇøºÍÄÚ´æ¿É¼ûÐÔ, ·ÀÖ¹ÖØÅÅÐò

4.volatileÌṩÄÚ´æ¿É¼ûÐÔ,·ÀÖ¹ÖØÅÅÐò£¬±£Ö¤64Î»ÔªËØ(double¡¢long)µÄÔ­×ÓÐÔ¶Áд

   
2881 ´Îä¯ÀÀ       29
Ïà¹ØÎÄÕÂ

Java΢·þÎñÐÂÉú´úÖ®Nacos
ÉîÈëÀí½âJavaÖеÄÈÝÆ÷
JavaÈÝÆ÷Ïê½â
Java´úÂëÖÊÁ¿¼ì²é¹¤¾ß¼°Ê¹Óð¸Àý
Ïà¹ØÎĵµ

JavaÐÔÄÜÓÅ»¯
Spring¿ò¼Ü
SSM¿ò¼Ü¼òµ¥¼òÉÜ
´ÓÁ㿪ʼѧjava±à³Ì¾­µä
Ïà¹Ø¿Î³Ì

¸ßÐÔÄÜJava±à³ÌÓëϵͳÐÔÄÜÓÅ»¯
JavaEE¼Ü¹¹¡¢ Éè¼ÆÄ£Ê½¼°ÐÔÄܵ÷ÓÅ
Java±à³Ì»ù´¡µ½Ó¦Óÿª·¢
JAVAÐéÄâ»úÔ­ÀíÆÊÎö