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

1Ôª 10Ôª 50Ôª





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



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
Java ²¢·¢±à³Ì£¨¸ß¼¶Æª£©
 
  2903  次浏览      27
 2018-7-9
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚcsdn£¬½éÉÜÁË Java ²¢·¢±à³Ìʵ¼ù£¬Unsafe Àà̽¾¿£¬LockSupport Àà̽¾¿µÈ¡£

Ò»¡¢Ç°ÑÔ

Java ²¢·¢±à³Ìʵ¼ùÖеϰ£º

±àдÕýÈ·µÄ³ÌÐò²¢²»ÈÝÒ×£¬¶ø±àдÕý³£µÄ²¢·¢³ÌÐò¾Í¸üÄÑÁË¡£Ïà±ÈÓÚ˳ÐòÖ´ÐеÄÇé¿ö£¬¶àÏ̵߳ÄḬ̈߳²È«ÎÊÌâÊÇ΢Ãî¶øÇÒ³öºõÒâÁϵģ¬ÒòΪÔÚûÓнøÐÐÊʵ±Í¬²½µÄÇé¿ö϶àÏß³ÌÖи÷¸ö²Ù×÷µÄ˳ÐòÊDz»¿ÉÔ¤ÆÚµÄ¡£

²¢·¢±à³ÌÏà±È Java ÖÐÆäËû֪ʶµãѧϰÆðÀ´Ãż÷Ïà¶Ô½Ï¸ß£¬Ñ§Ï°ÆðÀ´±È½Ï·Ñ¾¢£¬´Ó¶øµ¼ÖºܶàÈËÍû¶øÈ´²½£»

¶øÎÞÂÛÊÇÖ°³¡ÃæÊԺ͸߲¢·¢¸ßÁ÷Á¿µÄϵͳµÄʵÏÖÈ´»¹¶¼Àë²»¿ª²¢·¢±à³Ì£¬´Ó¶øµ¼ÖÂÄܹ»ÕæÕýÕÆÎÕ²¢·¢±à³ÌµÄÈ˲ųÉΪÊг¡±È½ÏÆÈÇÐÐèÇóµÄ¡£

±¾³¡ Chat ×÷Ϊ Java ²¢·¢±à³ÌÖ®ÃÀϵÁеĸ߼¶ÆªÖ®¶þ£¬Ö÷Òª½²½âÄÚÈÝÈçÏ£º£¨½¨ÒéÏÈÔĶÁ£ºJava ±à³ÌÖ®ÃÀ£º²¢·¢±à³Ì¸ß¼¶ÆªÖ®Ò» £©

rt.jar ÖÐ Unsafe ÀàÖ÷Òªº¯Êý½²½â£¬ Unsafe ÀàÌṩÁËÓ²¼þ¼¶±ðµÄÔ­×Ó²Ù×÷£¬¿ÉÒÔ°²È«µÄÖ±½Ó²Ù×÷ÄÚ´æ±äÁ¿£¬ÆäÔÚ JUC Ô´ÂëÖб»¹ã·ºµÄʹÓã¬Á˽âÆäÔ­ÀíΪÑо¿ JUC Ô´Âëµì¶¨ÁË»ù´¡¡£

rt.jar ÖÐ LockSupport ÀàÖ÷Òªº¯Êý½²½â£¬LockSupport ÊǸö¹¤¾ßÀ࣬Ö÷Òª×÷ÓÃÊÇ¹ÒÆðºÍ»½ÐÑỊ̈߳¬ÊÇ´´½¨ËøºÍÆäËüͬ²½ÀàµÄ»ù´¡£¬Á˽âÆäÔ­ÀíΪÑо¿ JUC ÖÐËøµÄʵÏֵ춨»ù´¡¡£

½²½â JDK8 ÐÂÔöÔ­×Ó²Ù×÷Àà LongAdder ʵÏÖÔ­Àí£¬²¢½²½â AtomicLong µÄȱµãÊÇʲô£¬LongAdder ÊÇÈçºÎ½â¾ö AtomicLong µÄȱµãµÄ£¬LongAdder ºÍ LongAccumulator ÊÇʲô¹ØÏµ£¿

JUC ²¢·¢°üÖв¢·¢×é¼þ CopyOnWriteArrayList µÄʵÏÖÔ­Àí£¬CopyOnWriteArrayList ÊÇÈçºÎͨ¹ýдʱ¿½±´ÊµÏÖ²¢·¢°²È«µÄ List£¿

¶þ¡¢ Unsafe Àà̽¾¿

JDK µÄ rt.jar °üÖÐµÄ Unsafe ÀàÌṩÁËÓ²¼þ¼¶±ðµÄÔ­×Ó²Ù×÷£¬Unsafe ÀïÃæµÄ·½·¨¶¼ÊÇ native ·½·¨£¬Í¨¹ýʹÓà JNI µÄ·½Ê½À´·ÃÎʱ¾µØ C++ ʵÏÖ¿â¡£ÏÂÃæÎÒÃÇ¿´Ï Unsafe ÌṩµÄ¼¸¸öÖ÷Òª·½·¨ÒÔ¼°±à³ÌʱºòÈçºÎʹÓà Unsafe Àà×öһЩÊÂÇé¡£

2.1 Ö÷Òª·½·¨½éÉÜ

long objectFieldOffset(Field field) ·½·¨

×÷Ó㺷µ»ØÖ¸¶¨µÄ±äÁ¿ÔÚËùÊôÀàµÄÄÚ´æÆ«ÒÆµØÖ·£¬Æ«ÒƵØÖ·½ö½öÔڸà Unsafe º¯ÊýÖзÃÎÊÖ¸¶¨×Ö¶ÎʱºòʹÓá£ÈçÏ´úÂëʹÓà unsafe »ñÈ¡AtomicLong ÖбäÁ¿ value ÔÚ AtomicLong ¶ÔÏóÖеÄÄÚ´æÆ«ÒÆ¡£

static { try {
valueOffset = unsafe.objectFieldOffset
(AtomicLong.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}

int arrayBaseOffset(Class arrayClass) ·½·¨

»ñÈ¡Êý×éÖеÚÒ»¸öÔªËØµÄµØÖ·

int arrayIndexScale(Class arrayClass) ·½·¨

»ñÈ¡Êý×éÖе¥¸öÔªËØÕ¼ÓõÄ×Ö½ÚÊý

boolean compareAndSwapLong(Object obj, long offset, long expect, long update) ·½·¨

±È½Ï¶ÔÏó obj ÖÐÆ«ÒÆÁ¿Îª offset µÄ±äÁ¿µÄÖµÊDz»ÊÇºÍ expect ÏàµÈ£¬ÏàµÈÔòʹÓà update Öµ¸üУ¬È»ºó·µ»Ø true£¬·ñÕß·µ»Ø false

public native long getLongVolatile(Object obj, long offset) ·½·¨

»ñÈ¡¶ÔÏó obj ÖÐÆ«ÒÆÁ¿Îª offset µÄ±äÁ¿¶ÔÓ¦µÄ volatile ÄÚ´æÓïÒåµÄÖµ¡£

void putLongVolatile(Object obj, long offset, long value) ·½·¨

ÉèÖà obj ¶ÔÏóÖÐÄÚ´æÆ«ÒÆÎª offset µÄ long ÐͱäÁ¿µÄֵΪ value£¬Ö§³Ö volatile ÄÚ´æÓïÒå¡£

void putOrderedLong(Object obj, long offset, long value) ·½·¨

ÉèÖà obj ¶ÔÏóÖÐ offset Æ«ÒÆµØÖ·¶ÔÓ¦µÄ long ÐÍ field µÄֵΪ value¡£ÕâÊÇÓÐÑÓ³ÙµÄ putLongVolatile ·½·¨£¬²¢²»±£Ö¤ÖµÐÞ¸Ä¶ÔÆäËüÏß³ÌÁ¢¿Ì¿É¼û¡£±äÁ¿Ö»ÓÐʹÓà volatile ÐÞÊβ¢ÇÒÆÚÍû±»ÒâÍâÐ޸ĵÄʱºòʹÓòÅÓÐÓá£

void park(boolean isAbsolute, long time)

×èÈûµ±Ç°Ị̈߳¬ÆäÖвÎÊý isAbsolute µÈÓÚ false ʱºò£¬time µÈÓÚ 0 ±íʾһֱ×èÈû£¬time ´óÓÚ 0 ±íʾµÈ´ýÖ¸¶¨µÄ time ºó×èÈûÏ̻߳ᱻ»½ÐÑ£¬Õâ¸ö time ÊǸöÏà¶ÔÖµ£¬ÊǸöÔöÁ¿Öµ£¬Ò²¾ÍÊÇÏà¶Ôµ±Ç°Ê±¼äÀÛ¼Ó time ºóµ±Ç°Ï߳̾ͻᱻ»½ÐÑ¡£

Èç¹û isAbsolute µÈÓÚ true£¬²¢ÇÒ time ´óÓÚ 0 ±íʾ×èÈûºóµ½Ö¸¶¨µÄʱ¼äµãºó»á±»»½ÐÑ£¬ÕâÀï time ÊǸö¾ø¶ÔµÄʱ¼ä£¬ÊÇijһ¸öʱ¼äµã»»ËãΪ ms ºóµÄÖµ¡£

ÁíÍâµ±ÆäËüÏ̵߳÷ÓÃÁ˵±Ç°×èÈûÏß³ÌµÄ interrupt ·½·¨ÖжÏÁ˵±Ç°Ïß³Ìʱºò£¬µ±Ç°Ïß³ÌÒ²»á·µ»Ø£¬µ±ÆäËüÏ̵߳÷ÓÃÁË unpark ·½·¨²¢ÇҰѵ±Ç°Ïß³Ì×÷Ϊ²ÎÊýʱºòµ±Ç°Ïß³ÌÒ²»á·µ»Ø¡£

void unpark(Object thread)

»½Ðѵ÷Óà park ºó×èÈûµÄỊ̈߳¬²ÎÊýΪÐèÒª»½ÐѵÄÏ̡߳£

ÏÂÃæÊÇ Jdk8 ÐÂÔöµÄ·½·¨£¬ÕâÀï¼òµ¥µÄÁгö Long ÀàÐͲÙ×÷µÄ·½·¨

long getAndSetLong(Object obj, long offset, long update) ·½·¨

»ñÈ¡¶ÔÏó obj ÖÐÆ«ÒÆÁ¿Îª offset µÄ±äÁ¿ volatile ÓïÒåµÄÖµ£¬²¢ÉèÖñäÁ¿ volatile ÓïÒåµÄֵΪ update ¡£

public final long getAndSetLong(Object obj, long offset, long update)
{ long l;
do
{
l = getLongVolatile(obj, offset);//(1)
} while (!compareAndSwapLong(obj, offset, l, update)); return l;
}

´Ó´úÂë¿ÉÖªÄÚ²¿´úÂë (1) ´¦Ê¹Óà getLongVolatile »ñÈ¡µ±Ç°±äÁ¿µÄÖµ£¬È»ºóʹÓà CAS Ô­×Ó²Ù×÷½øÐÐÉèÖÃÐÂÖµ£¬ÕâÀïʹÓà while Ñ­»·ÊÇ¿¼Âǵ½¶à¸öÏß³Ìͬʱµ÷ÓõÄÇé¿ö CAS ʧ°ÜºóÐèÒª×ÔÐýÖØÊÔ¡£

long getAndAddLong(Object obj, long offset, long addValue) ·½·¨

»ñÈ¡¶ÔÏó obj ÖÐÆ«ÒÆÁ¿Îª offset µÄ±äÁ¿ volatile ÓïÒåµÄÖµ£¬²¢ÉèÖñäÁ¿ÖµÎªÔ­Ê¼Öµ +addValue¡£

public final long getAndAddLong(Object obj, long offset, long addValue)
{ long l;
do
{
l = getLongVolatile(obj, offset);
} while (!compareAndSwapLong(obj, offset, l, l + addValue)); return l;
}

ÀàËÆ getAndSetLong µÄʵÏÖ£¬Ö»ÊÇÕâÀïʹÓÃCASµÄʱºòʹÓÃÁËԭʼֵ+´«µÝµÄÔöÁ¿²ÎÊý addValue µÄÖµ¡£

2.2 ÈçºÎʹÓà Unsafe Àà

¿´µ½ Unsafe Õâ¸öÀàÈç´ËÅ£²æ£¬Äã¿Ï¶¨»áÈ̲»×¡ß£ÏÂÏÂÃæ´úÂ룬ÆÚÍûÄܹ»Ê¹Óà Unsafe ×öµãÊÂÇé¡£

public class TestUnSafe { //»ñÈ¡UnsafeµÄʵÀý£¨2.2.1£©
static final Unsafe unsafe = Unsafe.getUnsafe(); //¼Ç¼±äÁ¿stateÔÚÀàTestUnSafeÖÐµÄÆ«ÒÆÖµ£¨2.2.2£©
static final long stateOffset; //±äÁ¿(2.2.3)
private volatile long state=0; static { try { //»ñÈ¡state±äÁ¿ÔÚÀàTestUnSafeÖÐµÄÆ«ÒÆÖµ(2.2.4)
stateOffset = unsafe.objectFieldOffset (TestUnSafe .class .get DeclaredField ("state"));
} catch (Exception ex) {
System.out.println (ex.getLocalizedMessage()); throw new Error(ex);
}
} public static void main (String[] args) { //´´½¨ÊµÀý£¬²¢ÇÒÉèÖÃstateֵΪ1(2.2.5)
TestUnSafe test = new TestUnSafe(); //(2.2.6)
Boolean sucess = unsafe.compareAndSwapInt (test, stateOffset, 0, 1);
System.out.println(sucess);
}
}

ÈçÉÏ´úÂ루2.2.1£©»ñÈ¡ÁË Unsafe µÄÒ»¸öʵÀý£¬´úÂ루2.2.3£©´´½¨ÁËÒ»¸ö±äÁ¿ state ³õʼ»¯Îª 0¡£

´úÂ루2.2.4£©Ê¹Óà unsafe.objectFieldOffset »ñÈ¡ TestUnSafe ÀàÀïÃæµÄ state ±äÁ¿ÔÚ TestUnSafe ¶ÔÏóÀïÃæµÄÄÚ´æÆ«ÒÆÁ¿µØÖ·²¢±£´æµ½ stateOffset ±äÁ¿¡£

´úÂ루2.2.6£©µ÷Óô´½¨µÄ unsafe ʵÀýµÄ compareAndSwapInt ·½·¨£¬ÉèÖà test ¶ÔÏóµÄ state ±äÁ¿µÄÖµ£¬¾ßÌåÒâ˼ÊÇÈç¹û test ¶ÔÏóÄÚ´æÆ«ÒÆÁ¿Îª stateOffset µÄ state µÄ±äÁ¿Îª 0£¬Ôò¸üиÃֵΪ 1¡£

ÔËÐÐÉÏÃæ´úÂëÎÒÃÇÆÚÍû»áÊä³ö true£¬È»¶øÖ´Ðкó»áÊä³öÈçϽá¹û£º

ΪÑо¿ÆäÔ­Òò£¬±ØÈ»Òª·­¿´ getUnsafe ´úÂ룬¿´¿´ÀïÃæ×öÁËɶ£º

private static final Unsafe theUnsafe = new Unsafe(); public static Unsafe getUnsafe(){ //£¨2.2.7£©
Class localClass = Reflection.getCallerClass(); //£¨2.2.8)
if (!VM.isSystemDomainLoader (localClass .getClassLoader ()) ) { throw new SecurityException ("Unsafe");
} return theUnsafe;
} //ÅÐ¶Ï paramClassLoader ÊDz»ÊÇBootStrap Àà¼ÓÔØÆ÷(2.2.9 )
public static boolean isSystemDomainLoader (ClassLoader paramClassLoader)
{ return paramClassLoader == null;
}

´úÂ루2.2.7£©»ñÈ¡µ÷Óà getUnsafe Õâ¸ö·½·¨µÄ¶ÔÏóµÄ Class ¶ÔÏó£¬ÕâÀïÊÇ TestUnSafe.class¡£

´úÂ루2.2.8£©ÅжÏÊDz»ÊÇ Bootstrap Àà¼ÓÔØÆ÷¼ÓÔØµÄ localClass£¬ÕâÀïÊÇ¿´ÊDz»ÊÇ Bootstrap ¼ÓÔØÆ÷¼ÓÔØÁË TestUnSafe.class¡£ºÜÃ÷ÏÔÓÉÓÚ TestUnSafe.class ÊÇʹÓà AppClassLoader ¼ÓÔØµÄ£¬ËùÒÔÕâÀïÖ±½ÓÅ׳öÁËÒì³£¡£

˼¿¼Ï£¬ÕâÀïΪºÎÒªÓÐÕâ¸öÅжÏÄÇ£¿

ÎÒÃÇÖªµÀ Unsafe ÀàÊÇÔÚ rt.jar ÀïÃæÌṩµÄ£¬¶ø rt.jar ÀïÃæµÄÀàÊÇʹÓà Bootstrap Àà¼ÓÔØÆ÷¼ÓÔØµÄ£¬¶øÎÒÃÇÆô¶¯ main º¯ÊýËùÔÚµÄÀàÊÇʹÓà AppClassLoader ¼ÓÔØµÄ¡£

ËùÒÔÔÚ main º¯ÊýÀïÃæ¼ÓÔØ Unsafe Ààʱºò¼øÓÚίÍлúÖÆ»áίÍиø Bootstrap È¥¼ÓÔØ Unsafe Àà¡£

Èç¹ûûÓдúÂ루2.2.8£©Õâ¼øÈ¨£¬ÄÇôÎÒÃÇÓ¦ÓóÌÐò¾Í¿ÉÒÔËæÒâʹÓà Unsafe ×öÊÂÇéÁË£¬¶ø Unsafe Àà¿ÉÒÔÖ±½Ó²Ù×÷Äڴ棬ÊDz»°²È«µÄ¡£

ËùÒÔ JDK ¿ª·¢×éÌØÒâ×öÁËÕâ¸öÏÞÖÆ£¬²»Èÿª·¢ÈËÔ±ÔÚÕý¹æÇþµÀÏÂʹÓà Unsafe À࣬¶øÊÇÔÚ rt.jar ÀïÃæµÄºËÐÄÀàÀïÃæÊ¹Óà Unsafe ¹¦ÄÜ¡£

ÄÇôÈç¹û¿ª·¢ÈËÔ±ÕæµÄÏëҪʵÀý»¯ Unsafe À࣬ʹÓà Unsafe µÄ¹¦ÄܸÃÈçºÎ×öÄÇ£¿

·½·¨ÓкܶàÖÖ£¬¼ÈÈ»Õý¹æÇþµÀ·ÃÎʲ»ÁË£¬ÄÇô¾ÍÍæµãºÚ¿Æ¼¼£¬Ê¹ÓÃÍòÄܵķ´ÉäÀ´»ñÈ¡ Unsafe ʵÀý·½·¨£º

public class TestUnSafe { static final Unsafe unsafe; static final long stateOffset; private volatile long state = 0; static { try { // ·´Éä»ñÈ¡ Unsafe µÄ³ÉÔ±±äÁ¿ theUnsafe£¨2.2.10£©
Field field = Unsafe.class.getDeclaredField ("theUnsafe"); // ÉèÖÃΪ¿É´æÈ¡£¨2.2.11£©
field.setAccessible(true); // »ñÈ¡¸Ã±äÁ¿µÄÖµ£¨2.2.12£©
unsafe = (Unsafe) field.get(null); //»ñÈ¡ state ÔÚ TestUnSafe ÖÐµÄÆ«ÒÆÁ¿ £¨2.2.13£©
stateOffset = unsafe.objectFieldOffset (TestUnSafe .class .get DeclaredField ("state"));
} catch (Exception ex) {
System.out.println(ex.getLocalizedMessage()); throw new Error(ex);
}
} public static void main(String[] args) {
TestUnSafe test = new TestUnSafe();
Boolean sucess = unsafe.compareAndSwapInt (test, stateOffset, 0, 1);
System.out.println (sucess);
}
}

ÈçÉÏ´úÂëͨ¹ý´úÂ루2.2.10£©£¬£¨2.2.11£©£¬£¨2.2.12£©·´Éä»ñÈ¡ unsafe µÄʵÀý£¬È»ºóÔËÐнá¹ûÊä³ö£º

Èý¡¢LockSupportÀà̽¾¿

JDK ÖÐµÄ rt.jar ÀïÃæµÄ LockSupport ÊǸö¹¤¾ßÀ࣬Ö÷Òª×÷ÓÃÊÇ¹ÒÆðºÍ»½ÐÑỊ̈߳¬ËüÊÇ´´½¨ËøºÍÆäËüͬ²½ÀàµÄ»ù´¡¡£

LockSupport ÀàÓëÿ¸öʹÓÃËüµÄÏ̶߳¼»á¹ØÁªÒ»¸öÐí¿ÉÖ¤,ĬÈϵ÷Óà LockSupport ÀàµÄ·½·¨µÄÏß³ÌÊDz»³ÖÓÐÐí¿ÉÖ¤µÄ£¬LockSupport ÄÚ²¿Ê¹Óà Unsafe ÀàʵÏÖ£¬ÏÂÃæ½éÉÜÏ LockSupport ÄڵöÖ÷Òªº¯Êý£º

void park() ·½·¨

Èç¹ûµ÷Óà park() µÄÏß³ÌÒѾ­Äõ½ÁËÓë LockSupport ¹ØÁªµÄÐí¿ÉÖ¤£¬Ôòµ÷Óà LockSupport.park() »áÂíÉÏ·µ»Ø£¬·ñÕßµ÷ÓÃÏ̻߳ᱻ½ûÖ¹²ÎÓëÏ̵߳ĵ÷¶È£¬Ò²¾ÍÊǻᱻ×èÈû¹ÒÆð¡£

ÈçÏ´úÂ룬ֱ½ÓÔÚ main º¯ÊýÀïÃæµ÷Óà park ·½·¨£¬×îÖÕ½á¹ûÖ»»áÊä³öbegin park!£¬È»ºóµ±Ç°Ï̻߳ᱻ¹ÒÆð£¬ÕâÊÇÒòΪĬÈÏϵ÷ÓÃÏß³ÌÊDz»³ÖÓÐÐí¿ÉÖ¤µÄ¡£

public static void main ( String[] args )
{
System.out.println ( "begin park!" );
LockSupport.park();
System.out.println ( "end park!" );
}

ÔÚÆäËüÏ̵߳÷Óà unpark(Thread thread) ·½·¨²¢ÇÒµ±Ç°Ïß³Ì×÷Ϊ²ÎÊýʱºò£¬µ÷ÓÃpark·½·¨±»×èÈûµÄÏ̻߳᷵»Ø¡£

ÁíÍâÆäËüÏ̵߳÷ÓÃÁË×èÈûÏß³ÌµÄ interrupt() ·½·¨£¬ÉèÖÃÁËÖжϱê־ʱºò»òÕßÓÉÓÚÏ̵߳ÄÐé¼Ù»½ÐÑÔ­Òòºó×èÈûÏß³ÌÒ²»á·µ»Ø£¬ËùÒÔµ÷Óà park() ×îºÃÒ²ÊÇÓÃÑ­»·Ìõ¼þÅжϷ½Ê½¡£

ÐèҪעÒâµÄÊǵ÷Óà park() ·½·¨±»×èÈûµÄÏ̱߳»ÆäËûÏß³ÌÖжϺó×èÈûÏ̷߳µ»ØÊ±ºò²¢²»»áÅ׳ö InterruptedException Òì³£¡£

void unpark(Thread thread) ·½·¨

µ±Ò»¸öÏ̵߳÷ÓÃÁË unpark ʱºò£¬Èç¹û²ÎÊý thread Ïß³ÌûÓгÖÓÐ thread Óë LockSupport Àà¹ØÁªµÄÐí¿ÉÖ¤£¬ÔòÈà thread Ï̳߳ÖÓС£

Èç¹û thread ֮ǰµ÷ÓÃÁË park() ±»¹ÒÆð£¬Ôòµ÷Óà unpark ºó£¬¸ÃÏ̻߳ᱻ»½ÐÑ¡£

Èç¹û thread ֮ǰûÓе÷Óà park£¬Ôòµ÷Óà unPark ·½·¨ºó£¬ÔÚµ÷Óà park() ·½·¨£¬»áÁ¢¿Ì·µ»Ø£¬ÉÏÃæ´úÂëÐÞ¸ÄÈçÏ£º

public static void main( String[] args )
{
System.out.println( "begin park!" ); //ʹµ±Ç°Ï̻߳ñÈ¡µ½Ðí¿ÉÖ¤
LockSupport.unpark(Thread.currentThread()); //Ôٴε÷ÓÃpark
LockSupport.park();
System.out.println( "end park!" );

}

Ôò»áÊä³ö£º
begin park!
end park!

ÏÂÃæÔÙÀ´¿´Ò»¸öÀý×ÓÀ´¼ÓÉî¶Ô park,unpark µÄÀí½â

public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() { @Override
public void run() {
System.out.println ("child thread begin park!"); // µ÷ÓÃpark·½·¨£¬¹ÒÆð×Ô¼º
LockSupport.park();
System.out.println ("child thread unpark!");
}
}); //Æô¶¯×ÓÏß³Ì
thread.start(); //Ö÷Ïß³ÌÐÝÃß1S
Thread.sleep(1000);
System.out.println ("main thread begin unpark!"); //µ÷ÓÃunparkÈÃthread Ï̳߳ÖÓÐÐí¿ÉÖ¤£¬È»ºópark·½·¨»á·µ»Ø
LockSupport.unpark(thread);
}

Êä³öΪ£º

child thread begin park!
main thread begin unpark!
child thread unpark!

ÉÏÃæ´úÂëÊ×ÏÈ´´½¨ÁËÒ»¸ö×ÓÏß³Ì thread£¬Æô¶¯ºó×ÓÏ̵߳÷Óà park ·½·¨£¬ÓÉÓÚĬÈÏ×ÓÏß³ÌûÓгÖÓÐÐí¿ÉÖ¤£¬»á°Ñ×Ô¼º¹ÒÆð¡£

Ö÷Ïß³ÌÐÝÃß 1s ΪµÄÊÇÖ÷Ïß³ÌÔÚµ÷Óà unpark ·½·¨Ç°ÈÃ×ÓÏß³ÌÊä³ö child thread begin park! ²¢×èÈû¡£

Ö÷Ïß³ÌÈ»ºóÖ´ÐÐ unpark ·½·¨£¬²ÎÊýΪ×ÓỊ̈߳¬Ä¿µÄÊÇÈÃ×ÓÏ̳߳ÖÓÐÐí¿ÉÖ¤£¬È»ºó×ÓÏ̵߳÷ÓÃµÄ park ·½·¨¾Í·µ»ØÁË¡£

park ·½·¨·µ»ØÊ±ºò²»»á¸æËßÄãÊÇÒòΪºÎÖÖÔ­Òò·µ»Ø£¬ËùÒÔµ÷ÓÃÕßÐèÒª¸ù¾Ý֮ǰÊÇ´¦ÓÚʲôĿǰµ÷ÓÃµÄ park ·½·¨£¬Ôٴμì²éÌõ¼þÊÇ·ñÂú×㣬Èç¹û²»Âú×ãµÄ»°»¹ÐèÒªÔٴε÷Óà park ·½·¨¡£

ÀýÈ磬Ïß³ÌÔÚ·µ»ØÊ±µÄÖжÏ״̬£¬¸ù¾Ýµ÷ÓÃǰºóÖжÏ״̬¶Ô±È¾Í¿ÉÒÔÅжÏÊDz»ÊÇÒòΪ±»Öжϲŷµ»ØµÄ¡£

ΪÁË˵Ã÷µ÷Óà park ·½·¨ºóµÄÏ̱߳»ÖжϺó»á·µ»Ø£¬ÐÞ¸ÄÉÏÃæÀý×Ó´úÂ룬ɾ³ý LockSupport.unpark ( thread ) ; È»ºóÌí¼Ó thread .interrupt(); ´úÂëÈçÏ£º

public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() { @Override
public void run() {
System.out.println ("child thread begin park!"); // µ÷ÓÃpark·½·¨£¬¹ÒÆð×Ô¼º,Ö»Óб»ÖжϲŻáÍ˳öÑ­»·
while (!Thread.currentThread ().isInterrupted()) {
LockSupport.park();
}
System.out.println ("child thread unpark!");
}
}); // Æô¶¯×ÓÏß³Ì
thread.start(); // Ö÷Ïß³ÌÐÝÃß1S
Thread.sleep(1000);
System.out.println ("main thread begin unpark!"); // ÖжÏ×ÓÏß³ÌÏß³Ì
thread.interrupt();
}

Êä³öΪ£º

child thread begin park!
main thread begin unpark!
child thread unpark!

ÈçÉÏ´úÂëÒ²¾ÍÊÇÖ»Óе±×ÓÏ̱߳»ÖжϺó×ÓÏ̲߳ŻáÔËÐнáÊø£¬Èç¹û×ÓÏ̲߳»±»Öжϣ¬¼´Ê¹Äãµ÷Óà unPark(thread) ×ÓÏß³ÌÒ²²»»á½áÊø¡£

void parkNanos(long nanos)º¯Êý

ºÍ park ÀàËÆ£¬Èç¹ûµ÷Óà park µÄÏß³ÌÒѾ­Äõ½ÁËÓë LockSupport ¹ØÁªµÄÐí¿ÉÖ¤£¬Ôòµ÷Óà LockSupport.park() »áÂíÉÏ·µ»Ø£¬²»Í¬ÔÚÓÚÈç¹ûûÓÐÄõ½Ðí¿Éµ÷ÓÃÏ̻߳ᱻ¹ÒÆð nanos ʱ¼äºóÔÚ·µ»Ø¡£

park »¹Ö§³ÖÈý¸ö´øÓÐ blocker ²ÎÊýµÄ·½·¨£¬µ±Ïß³ÌÒòΪûÓгÖÓÐÐí¿ÉµÄÇé¿öϵ÷Óà park ±»×èÈû¹ÒÆðʱºò£¬Õâ¸ö blocker ¶ÔÏó»á±»¼Ç¼µ½¸ÃÏß³ÌÄÚ²¿¡£

ʹÓÃÕï¶Ï¹¤¾ß¿ÉÒÔ¹Û²ìÏ̱߳»×èÈûµÄÔ­Òò£¬Õï¶Ï¹¤¾ßÊÇͨ¹ýµ÷ getBlocker(Thread) ·½·¨À´»ñÈ¡¸Ã blocker ¶ÔÏóµÄ£¬ËùÒÔ JDK ÍÆ¼öÎÒÃÇʹÓôøÓÐ blocker ²ÎÊýµÄ park ·½·¨,²¢ÇÒ blocker ÉèÖÃΪ this£¬ÕâÑùµ±ÄÚ´æ dump ÅŲéÎÊÌâʱºò¾ÍÄÜÖªµÀÊÇÄǸöÀà±»×èÈûÁË¡£

ÀýÈçÏÂÃæ´úÂ룺

public class TestPark { public void testPark(){
LockSupport.park();//(1)
} public static void main(String[] args) {
TestPark testPark = new TestPark();
testPark.testPark();
}
}

ÔËÐкóʹÓà jstack pid ²é¿´Ï̶߳Ñջʱºò¿ÉÒÔ¿´µ½ÈçÏ£º

ÐÞ¸Ä ´úÂ루1£©Îª LockSupport.park(this) ºóÔËÐÐÔÚ jstack pid ½á¹ûΪ£º

¿É֪ʹÓôø blocker µÄ park ·½·¨ºó£¬Ï̶߳ÑÕ»¿ÉÒÔÌṩ¸ü¶àÓйØ×èÈû¶ÔÏóµÄÐÅÏ¢¡£

park(Object blocker) º¯Êý

public static void park(Object blocker) { //»ñÈ¡µ÷ÓÃÏß³Ì
Thread t = Thread.currentThread(); //ÉèÖøÃÏß³ÌµÄ blocker ±äÁ¿
setBlocker (t, blocker); //¹ÒÆðÏß³Ì
UNSAFE.park (false, 0L); //Ï̱߳»¼¤»îºóÇå³ý blocker ±äÁ¿£¬ÒòΪһ°ã¶¼ÊÇÏß³Ì×èÈûʱºò²Å·ÖÎöÔ­Òò
setBlocker(t, null);
}

Thread ÀàÀïÃæÓиö±äÁ¿ volatile Object parkBlocker ÓÃÀ´´æ·Å park ´«µÝµÄ blocker ¶ÔÏó£¬Ò²¾ÍÊÇ°Ñ blocker ±äÁ¿´æ·Åµ½Á˵÷Óà park ·½·¨µÄÏ̵߳ijÉÔ±±äÁ¿ÀïÃæ¡£

void parkNanos(Object blocker, long nanos) º¯Êý

Ïà±È park(Object blocker) ¶àÁ˸ö³¬Ê±Ê±¼ä¡£

void parkUntil(Object blocker, long deadline)

parkUntil µÄ´úÂëÈçÏ£º

public static void parkUntil (Object blocker, long deadline) {
Thread t = Thread.currentThread();
setBlocker(t, blocker); //isAbsolute = true,time= deadline ;±íʾµ½ deadline ʱ¼äʱºòºó·µ»Ø
UNSAFE.park (true, deadline);
setBlocker (t, null);
}

¿ÉÖªÊÇÉèÖÃÒ»¸ö deadline£¬Ê±¼äµ¥Î»Îª milliseconds£¬ÊÇ´Ó 1970 µ½ÏÖÔÚijһ¸öʱ¼äµã»»ËãΪºÁÃëºóµÄÖµ£¬Õâ¸öºÍ parkNanos(Object blocker, long nanos) Çø±ðÊǺóÕßÊÇ´Óµ±Ç°ËãµÈ´ý nanos ʱ¼ä£¬¶øÇ°ÕßÊÇÖ¸¶¨Ò»¸öʱ¼äµã¡£

±ÈÈçÎÒÐèÒªµÈ´ýµ½ 2017.12.11 ÈÕ 12:00:00£¬Ôò°ÉÕâ¸öʱ¼äµãת»»Îª´Ó 1970 Äêµ½Õâ¸öʱ¼äµãµÄ×ܺÁÃëÊý¡£

×îºóÔÚ¿´Ò»¸öÀý×Ó

class FIFOMutex { private final AtomicBoolean locked = new AtomicBoolean (false); private final Queue <Thread> waiters = new ConcurrentLinkedQueue <Thread> (); public void lock() { boolean wasInterrupted = false ;
Thread current = Thread.currentThread ();
waiters .add (current); // Ö»ÓжÓÊ×µÄÏ߳̿ÉÒÔ»ñÈ¡Ëø£¨1£©
while (waiters.peek() != current || !locked.compareAndSet (false, true)) {
LockSupport.park (this); if (Thread.interrupted()) // £¨2£©
wasInterrupted = true;
}
waiters.remove(); if (wasInterrupted) // £¨3£©
current.interrupt ();
} public void unlock() {
locked.set (false);
LockSupport .unpark (waiters.peek());
}
}

ÕâÊÇÒ»¸öÏȽøÏȳöµÄËø£¬Ò²¾ÍÊÇÖ»ÓжÓÁÐÊ×ÔªËØ¿ÉÒÔ»ñÈ¡Ëø£¬´úÂ루1£©´¦Èç¹ûµ±Ç°Ï̲߳»ÊǶÓÊ×»òÕßµ±Ç°ËøÒѾ­±»ÆäËüÏ̻߳ñÈ¡£¬Ôòµ÷ÓÃpark·½·¨¹ÒÆð×Ô¼º¡£

È»ºó´úÂ루2£©´¦Åжϣ¬Èç¹û park ·½·¨ÊÇÒòΪ±»Öж϶ø·µ»Ø£¬ÔòºöÂÔÖжϣ¬²¢ÇÒÖØÖÃÖжϱêÖ¾£¬Ö»×ö¸ö±ê¼Ç£¬È»ºóÔÙ´ÎÅжϵ±Ç°Ïß³ÌÊDz»ÊǶÓÊ×ÔªËØ»òÕßµ±Ç°ËøÊÇ·ñÒѾ­±»ÆäËüÏ̻߳ñÈ¡£¬Èç¹ûÊÇÔò¼ÌÐøµ÷Óà park ·½·¨¹ÒÆð×Ô¼º¡£

È»ºó´úÂ루3£©ÖÐÈç¹û±ê¼ÇΪ true ÔòÖжϸÃỊ̈߳¬Õâ¸öÔõôÀí½âÄÇ£¿ÆäʵÒâ˼ÊÇÆäËüÏß³ÌÖжÏÁ˸ÃỊ̈߳¬ËäÈ»ÎÒ¶ÔÖжÏÐźŲ»¸ÐÐËȤ£¬ºöÂÔËü£¬µ«ÊDz»´ú±íÆäËüÏ̶߳ԸñêÖ¾²»¸ÐÐËȤ£¬ËùÒÔÒª»Ö¸´Ï¡£

   
2903 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

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

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

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