µ±Ç°Î»ÖãºÖ÷Ò³ > ²é¿´ÄÚÈÝ

½Ì´ó¼ÒÈçºÎÊÖдһ¸öAQS£¿

·¢²¼Ê±¼ä£º2021-04-24 00:00| ÓРλÅóÓѲ鿴

¼ò½é£ºÊÖдһ¸öAQS AQS¼´AbstractQueuedSynchronizer£¬ÊÇÓÃÀ´ÊµÏÖËøºÍÏß³Ìͬ²½µÄÒ»¸ö¹¤¾ßÀà¡£´ó²¿·Ö²Ù×÷»ùÓÚCASºÍFIFO¶ÓÁÐÀ´ÊµÏÖ¡£ Èç¹ûÈÃÎÒÃÇ×Ô¼º»ùÓÚAPIÀ´ÊµÏÖÒ»¸öËø£¬ÊµÏÖ¿ÉÒÔ·ÖΪ¼¸¸ö´ó²¿·Ö ¼ÓËø ½âËø Èë¶Ó ³ö¶Ó ×èÈû »½ÐÑ ÎÒÃÇÀ´ÏëÒ»ÏÂÕ⼸¸ö²¿·ÖµÄʵÏÖ ¼ÓËø¡­¡­

ÊÖдһ¸öAQS

AQS¼´AbstractQueuedSynchronizer£¬ÊÇÓÃÀ´ÊµÏÖËøºÍÏß³Ìͬ²½µÄÒ»¸ö¹¤¾ßÀà¡£´ó²¿·Ö²Ù×÷»ùÓÚCASºÍFIFO¶ÓÁÐÀ´ÊµÏÖ¡£

Èç¹ûÈÃÎÒÃÇ×Ô¼º»ùÓÚAPIÀ´ÊµÏÖÒ»¸öËø£¬ÊµÏÖ¿ÉÒÔ·ÖΪ¼¸¸ö´ó²¿·Ö

  • ¼ÓËø
  • ½âËø
  • Èë¶Ó
  • ³ö¶Ó
  • ×èÈû
  • »½ÐÑ

ÎÒÃÇÀ´ÏëÒ»ÏÂÕ⼸¸ö²¿·ÖµÄʵÏÖ

¼ÓËø

1.ÓÃÒ»¸ö±äÁ¿state×÷ΪËøµÄ±ê־λ£¬Ä¬ÈÏÊÇ0£¬±íʾ´ËʱËùÓÐÏ̶߳¼¿ÉÒÔ¼ÓËø£¬¼ÓËøµÄʱºòͨ¹ýcas½«state´Ó0±äΪ1£¬casÖ´Ðгɹ¦±íʾ¼ÓËø³É¹¦

2.µ±ÓÐÏß³ÌÕ¼ÓÐÁËËø£¬ÕâʱºòÓÐÆäËûÏß³ÌÀ´¼ÓËø£¬Åжϵ±Ç°À´ÇÀËøµÄÏß³ÌÊDz»ÊÇÕ¼ÓÃËøµÄÏß³Ì?ÊÇ£ºÖØÈëËø£¬state+1£¬µ±ÊͷŵÄʱºòstate-1£¬ÓÃstate±íʾ¼ÓËøµÄ´ÎÊý ·ñ£º¼ÓËøʧ°Ü£¬½«Ï̷߳ÅÈëµÈ´ý¶ÓÁУ¬²¢ÇÒ×èÈû

3.ÓÐûÓÐʲôÆäËû¿ÉÒÔÓÅ»¯µÄµØ·½?µ±·ÅÈëµÈ´ý¶ÓÁеÄʱºò£¬¿´¿´ÓÐûÓÐÆäËûÏß³Ì?ÓУ¬Ëø±»Õ¼ÓÃÁË£¬²¢ÇÒÂÖ²»µ½µ±Ç°Ïß³ÌÀ´ÇÀ£¬Ö±½Ó×èÈû¾ÍÐÐÁË ÔÚ·ÅÈë¶ÓÁÐʱºò£¬Í¨¹ýcasÔÙ³¢ÊÔ»ñÈ¡Ò»²¨Ëø£¬Èç¹û»ñÈ¡³É¹¦£¬¾Í²»ÓÃ×èÈûÁË£¬Ìá¸ßÁËЧÂÊ

½âËø

1.ͨ¹ýcas¶Ôstate-1£¬Èç¹ûÊÇÖØÈëËø£¬ÊÍ·ÅÒ»´Î¼õÒ»´Î£¬µ±state=0ʱ±íʾËø±»ÊÍ·Å¡£2.»½Ðѵȴý¶ÓÁÐÖеÄÏß³Ì

Èë¶Ó

Èë¶ÓÕâ¸ö¹ý³ÌºÍÎÒÃÇƽ³£Ê¹ÓõĶÓÁв»Í¬¡£ÎÒÃÇƽ³£Ê¹ÓõĶÓÁÐÿ´ÎÉú³ÉÒ»¸ö½Úµã·ÅÈë¼´¿É¡£

¶øAQS¶ÓÁУ¬µ±¶ÓÁÐΪ¿Õʱ£¬µÚÒ»´ÎÉú³ÉÁ½¸ö½Úµã£¬µÚÒ»¸ö½Úµã´ú±íµ±Ç°Õ¼ÓÐËøµÄỊ̈߳¬µÚ¶þ¸ö½ÚµãΪÇÀËøʧ°ÜµÄ½Úµã¡£²»Îª¿ÕµÄʱºò£¬Ã¿´ÎÉú³ÉÒ»¸ö½Úµã·ÅÈë¶Óβ¡£

¡¸µ±°ÑÏ̷߳ÅÈë¶ÓÁÐÖÐʱ£¬ºóÐøÓ¦¸Ã×öÄÄЩ²Ù×÷ÄØ?¡¹

Èç¹ûÈÃÄãдÊDz»ÊÇÖ±½Ó·ÅÈë¶ÓÁÐÖоÍÍêÊÂÁË?µ«Doug LeaÊÇÕâÑù×öµÄ

  1. Èç¹ûµ±Ç°Ïß³ÌÊǶÓÁÐÖеĵڶþ¸ö½ÚµãÔòÔÙ³¢ÊÔÇÀÒ»ÏÂËø(²»Êǵڶþ¸ö½Úµã¾Í²»ÓÃÇÀÀ´£¬ÂÖ²»µ½)£¬ÕâÑù±ÜÃâÁËƵ·±µÄ×èÈûºÍ»½ÐÑỊ̈߳¬Ìá¸ßÁËЧÂÊ
  2. ÉÏÄÖÖÓ£¬ÈÃÉÏÒ»¸öÏß³ÌÀ´»½ÐÑ×Ô¼º(ºóÐø»á˵µ½£¬¼´¸ü¸ÄÉÏÒ»¸ö½ÚµãµÄwaitStatus)
  3. ×èÈû

³ö¶Ó

µ±AÏß³ÌÊÍ·ÅËø£¬»½ÐѶÓÁÐÖеÄBỊ̈߳¬AÏ̻߳á´Ó¶ÓÁÐÖÐɾ³ý

Ädzö¶ÓÕâ¸öÊÂÇéÓÉË­À´×ö?ÊÇÓɱ»»½ÐѵÄÏß³ÌÀ´×ö£¬¼´BÏß³Ì

×èÈûºÍ»½ÐÑ

×èÈûºÍ»½ÐÑÏ̵߳÷ÓÃapi¼´¿É

  1. // ×èÈûÏ̠߳
  2. LockSupport.park(this) 
  3. // »½ÐÑÏ̠߳
  4. LockSupport.unpark(this) 

¶ÀÕ¼ËøµÄ»ñÈ¡ºÍÊÍ·Å

JUCÖеÄÐí¶à²¢·¢¹¤¾ßÀàReentrantLock£¬CountDownLatchµÈµÄʵÏÖ¶¼ÒÀÀµAbstractQueuedSynchronizer

AbstractQueuedSynchronizer¶¨ÒåÁËÒ»¸öËøʵÏÖµÄÄÚ²¿Á÷³Ì£¬¶øÈçºÎ¼ÓËøºÍ½âËøÔòÔÚ¸÷¸ö×ÓÀàÖÐʵÏÖ£¬µäÐ͵ÄÄ£°å·½·¨Ä£Ê½

AQSÄÚ²¿Î¬»¤ÁËÒ»¸öFIFOµÄ¶ÓÁÐ(µ×²ãʵÏÖ¾ÍÊÇË«ÏòÁ´±í)£¬Í¨¹ý¸Ã¶ÓÁÐÀ´ÊµÏÖÏ̵߳IJ¢·¢·ÃÎÊ¿ØÖÆ£¬¶ÓÁÐÖеÄÔªËØÊÇÒ»¸öNode½Úµã

  1. static final class Node { 
  2.  //±íʾµ±Ç°Ïß³ÌÒÔ¹²Ïíģʽ³ÖÓÐËø 
  3.  static final Node SHARED = new Node(); 
  4.  //±íʾµ±Ç°Ïß³ÌÒÔ¶Àռģʽ³ÖÓÐËø 
  5.  static final Node EXCLUSIVE = null
  6.  
  7.  static final int CANCELLED =  1; 
  8.  static final int SIGNAL    = -1; 
  9.  static final int CONDITION = -2; 
  10.  static final int PROPAGATE = -3; 
  11.  
  12.  //µ±Ç°½ÚµãµÄ״̬ 
  13.  volatile int waitStatus; 
  14.  
  15.  //Ç°¼Ì½Úµã 
  16.  volatile Node prev; 
  17.  
  18.  //ºó¼Ì½Úµã 
  19.  volatile Node next
  20.  
  21.  //µ±Ç°Ï̠߳
  22.  volatile Thread thread; 
  23.  
  24.  //´æ´¢ÔÚcondition¶ÓÁÐÖеĺó¼Ì½Úµã 
  25.  Node nextWaiter; 
  26.  

waitStatus(ĬÈÏÊÇ0)±íʾ½ÚµãµÄ״̬£¬°üº¬µÄ״̬ÓÐ

״̬ Öµ º¬Òå
CANCELLED 1 Ï̻߳ñÈ¡ËøµÄÇëÇóÒѾ­È¡Ïû
SIGNAL -1 ±íʾµ±Ç°½ÚµãµÄµÄºó¼Ì½Úµã½«Òª»òÕßÒѾ­±»×èÈû£¬ÔÚµ±Ç°½ÚµãÊͷŵÄʱºòÐèÒªunparkºó¼Ì½Úµã
CONDITION -2 ±íʾµ±Ç°½ÚµãÔڵȴýcondition£¬¼´ÔÚcondition¶ÓÁÐÖÐ
PROPAGATE -3 ±íʾ״̬ÐèÒªÏòºó´«²¥£¬½öÔÚ¹²ÏíģʽÏÂʹÓã©
  0 Node±»³õʼ»¯ºóµÄĬÈÏÖµ£¬µ±Ç°½ÚµãÔÚ¶ÓÁÐÖеȴý»ñÈ¡Ëø

ÔÙÀ´¿´AbstractQueuedSynchronizerÕâ¸öÀàµÄÊôÐÔ

  1. //µÈ´ý¶ÓÁеÄÍ·½Úµã 
  2. private transient volatile Node head; 
  3.  
  4. //µÈ´ý¶ÓÁеÄβ½Úµã 
  5. private transient volatile Node tail; 
  6.  
  7. //¼ÓËøµÄ״̬£¬ÔÚ²»Í¬×ÓÀàÖÐÓв»Í¬µÄÒâÒå 
  8. private volatile int state; 

¡¸Õâ¸östateÔÚ²»Í¬µÄ×ÓÀàÖÐÓв»Í¬µÄº¬Ò塹

¡¸ReentrantLock¡¹£ºstate±íʾ¼ÓËøµÄ´ÎÊý£¬Îª0±íʾûÓб»¼ÓËø£¬Îª1±íʾ±»¼ÓËø1´Î£¬Îª2±íʾ±»¼ÓËø2´Î£¬ÒòΪReentrantLockÊÇÒ»¸ö¿ÉÒÔÖØÈëµÄËø¡¸CountDownLatch¡¹£ºstate±íʾһ¸ö¼ÆÊýÆ÷£¬µ±state>0ʱ£¬Ï̵߳÷ÓÃawait»á±»×èÈû£¬µ±stateÖµ±»¼õÉÙΪ0ʱ£¬Ï̻߳ᱻ»½ÐÑ¡¸Semaphore¡¹£ºstate±íʾ×ÊÔ´µÄÊýÁ¿£¬state>0ʱ£¬¿ÉÒÔ»ñÈ¡×ÊÔ´£¬²¢½«state-1£¬µ±state=0ʱ£¬»ñÈ¡²»µ½×ÊÔ´£¬´ËʱÏ̻߳ᱻ×èÈû¡£µ±×ÊÔ´±»ÊÍ·Åʱ£¬state+1£¬´ËʱÆäËûÏ߳̿ÉÒÔ»ñµÃ×ÊÔ´

AbstractQueuedSynchronizerÖеÄFIFO¶ÓÁÐÊÇÓÃË«ÏòÁ´±íÀ´ÊµÏÖµÄ

ÔÚÕâÀï²åÈëͼƬÃèÊö

AQSÌṩÁ˶ÀÕ¼ËøºÍ¹²ÏíËøÁ½ÖÖ¼ÓËø·½Ê½£¬Ã¿ÖÖ·½Ê½¶¼ÓÐÏìÓ¦ÖжϺͲ»ÏìÓ¦ÖжϵÄÇø±ð£¬ËùÒÔAQSµÄËø¿ÉÒÔ·ÖΪÈçÏÂËÄÀà

  1. ²»ÏìÓ¦ÖжϵĶÀÕ¼Ëø(acquire)
  2. ÏìÓ¦ÖжϵĶÀÕ¼Ëø(acquireInterruptibly)
  3. ²»ÏìÓ¦ÖжϵĹ²ÏíËø(acquireShared)
  4. ÏìÓ¦ÖжϵĹ²ÏíËø(acquireSharedInterruptibly)

¶øÊÍ·ÅËøµÄ·½Ê½Ö»ÓÐÁ½ÖÖ

  1. ¶ÀÕ¼ËøµÄÊÍ·Å(release)
  2. ¹²ÏíËøµÄÊÍ·Å(releaseShared)

²»ÏìÓ¦ÖжϵĶÀÕ¼Ëø

ÒÔReentrantLockΪÀý£¬´Ó¼ÓËøÕâÒ»²¿·Ö¿ªÊ¼·ÖÎö

  1. // µ÷ÓÃReentrantLock.FairSync#lock·½·¨Æäʵ¾ÍÊǵ÷ÓÃacquire(1); 
  2. public final void acquire(int arg) { 
  3.  if (!tryAcquire(arg) && 
  4.   acquireQueued(addWaiter(Node.EXCLUSIVE), arg))//»ñÈ¡µ½Ëø·µ»Øfalse£¬·ñÔò·µ»Øtrue 
  5.   selfInterrupt();//µ±Ç°Ï߳̽«×Ô¼ºÖжϠ
  1. Ïȳ¢ÊÔ»ñÈ¡£¬Èç¹û»ñÈ¡µ½Ö±½ÓÍ˳ö£¬·ñÔò½øÈë2
  2. »ñÈ¡Ëøʧ°Ü£¬ÒÔ¶Àռģʽ½«Ḭ̈߳ü×°³ÉNode·Åµ½¶ÓÁÐÖÐ
  3. Èç¹û·ÅÈëµÄ½ÚµãÊǶÓÁеĵڶþ¸ö½Úµã£¬ÔòÔÙ³¢ÊÔ»ñÈ¡Ëø£¬ÒòΪ´ËʱËøÓпÉÄÜÊÍ·ÅÀ࣬²»Êǵڶþ¸ö½Úµã¾Í²»Óó¢ÊÔÁË£¬ÒòΪÂÖ²»µ½¡£Èç¹û»ñÈ¡µ½ËøÔò½«µ±Ç°½ÚµãÉèΪhead½Úµã£¬Í˳ö£¬·ñÔò½øÈë4
  4. ÉèÖúÃÄÖÖÓºó½«×Ô¼º×èÈû
  5. Ï̱߳»»½ÐÑ£¬ÖØоºÕùËø£¬»ñÈ¡Ëø³É¹¦£¬¼ÌÐøÖ´ÐС£Èç¹ûÏ̷߳¢Éú¹ýÖжϣ¬Ôò×îºóÖØÖÃÖжϱê־λλtrue£¬¼´Ö´ÐÐselfInterrupt()·½·¨

¡¸´Ó´úÂë²ãÃæÏêϸ·ÖÎöÒ»²¨£¬×ßÆð¡¹

tryAcquireÊÇÈÃ×ÓÀàʵÏÖµÄ

  1. protected boolean tryAcquire(int arg) { 
  2.  throw new UnsupportedOperationException(); 

ÕâÀïͨ¹ýÅ׳öÒì³£À´¸æËß×ÓÀàÒªÖØдÕâ¸ö·½·¨£¬ÎªÊ²Ã´²»½«Õâ¸ö·½·¨¶¨ÒåΪabstract·½·¨ÄØ?ÒòΪAQSÓÐ2ÖÖ¹¦ÄÜ£¬¶ÀÕ¼ºÍ¹²Ïí£¬Èç¹ûÓÃabstractÐÞÊΣ¬Ôò×ÓÀàÐèҪͬʱʵÏÖÁ½ÖÖ¹¦Äܵķ½·¨£¬¶Ô×ÓÀ಻ÓѺÃ

  1. µ±¶ÓÁв»Îª¿Õ£¬³¢ÊÔ½«Ð½ڵãͨ¹ýCASµÄ·½Ê½ÉèÖÃΪβ½Úµã£¬Èç¹û³É¹¦£¬·µ»Ø¸½¼Ó×ŵ±Ç°Ï̵߳Ľڵã
  2. µ±¶ÓÁÐΪ¿Õ£¬»òÕßнڵãͨ¹ýCASµÄ·½Ê½ÉèÖÃΪβ½Úµãʧ°Ü£¬½øÈëenq·½·¨
  1. private Node addWaiter(Node mode) { 
  2.  Node node = new Node(Thread.currentThread(), mode); 
  3.  Node pred = tail; 
  4.  if (pred != null) { 
  5.   node.prev = pred; 
  6.   if (compareAndSetTail(pred, node)) { 
  7.    pred.next = node; 
  8.    return node; 
  9.   } 
  10.  } 
  11.  enq(node); 
  12.  return node; 
  1. µ±¶ÓÁв»Îª¿Õ£¬Ò»Ö±CAS£¬Ö±µ½°Ñнڵã·ÅÈë¶Óβ
  2. µ±¶ÓÁÐΪ¿Õ£¬ÏÈÍù¶ÔÁÐÖзÅÈëÒ»¸ö½Úµã£¬ÔÚ°Ñ´«ÈëµÄ½ÚµãCASΪβ½Úµã

¡¸Ç°ÃæÒѾ­Ëµ¹ýÁ˹þ£¬AQS¶ÓÁÐΪ¿Õʱ£¬µÚÒ»´Î»á·ÅÈë2¸ö½Úµã¡¹

  1. private Node enq(final Node node) { 
  2.  for (;;) { 
  3.   Node t = tail; 
  4.   // ¶ÓÁÐΪ¿Õ£¬½øÐгõʼ»¯£¬ 
  5.   if (t == null) { 
  6.    if (compareAndSetHead(new Node())) 
  7.     tail = head; 
  8.   } else { 
  9.    node.prev = t; 
  10.    if (compareAndSetTail(t, node)) { 
  11.     t.next = node; 
  12.     return t; 
  13.    } 
  14.   } 
  15.  } 

·ÅÈë¶ÓÁкó»¹Òª¸Éʲô?

  1. Èç¹ûÊǵڶþ¸ö½ÚµãÔÙ³¢ÊÔ»ñÈ¡Ò»²¨Ëø£¬ÒòΪ´ËʱÓпÉÄÜËøÒѾ­ÊÍ·ÅÁË£¬ÆäËû½Úµã¾Í²»ÓÃÁË£¬ÒòΪ»¹ÂÖ²»µ½
  2. ÉÏÄÖÖÓ£¬ÈñðµÄÏ̻߳½ÐÑ×Ô¼º
  3. ×èÈû×Ô¼º
  1. // ×ÔÐý»ñÈ¡Ëø£¬Ö±µ½»ñÈ¡Ëø³É¹¦£¬»òÕßÒì³£Í˳ö 
  2. // µ«ÊDz¢²»ÊÇbusy acquire£¬ÒòΪµ±»ñȡʧ°Üºó»á±»¹ÒÆð£¬ÓÉÇ°Çý½ÚµãÊÍ·ÅËøʱ½«Æ份ÐÑ 
  3. // Í¬Ê±ÓÉÓÚ»½ÐѵÄʱºò¿ÉÄÜÓÐÆäËûÏ߳̾ºÕù£¬ËùÒÔ»¹ÐèÒª½øÐг¢ÊÔ»ñÈ¡Ëø£¬ÌåÏֵķǹ«Æ½ËøµÄ¾«Ëè¡£ 
  4. final boolean acquireQueued(final Node node, int arg) { 
  5.  boolean failed = true
  6.  try { 
  7.   boolean interrupted = false
  8.   for (;;) { 
  9.    // »ñÈ¡Ç°¼Ì½Úµã 
  10.    final Node p = node.predecessor(); 
  11.    // node½ÚµãµÄÇ°¼Ì½ÚµãÊÇhead½Úµã£¬³¢ÊÔ»ñÈ¡Ëø£¬Èç¹û³É¹¦ËµÃ÷head½ÚµãÒѾ­ÊÍ·ÅËøÁË 
  12.    // ½«nodeÉèΪhead¿ªÊ¼ÔËÐÐ(headÖв»°üº¬thread) 
  13.    if (p == head && tryAcquire(arg)) { 
  14.     setHead(node); 
  15.     // ½«µÚÒ»¸ö½Úµã³ö¶Ó 
  16.     p.next = null; // help GC 
  17.     failed = false
  18.     return interrupted; 
  19.    } 
  20.    // »ñÈ¡Ëøʧ°ÜºóÊÇ·ñ¿ÉÒÔ¹ÒÆð 
  21.    // Èç¹û¿ÉÒÔ¹ÒÆð£¬Ôò×èÈûµ±Ç°Ị̈߳¨»ñÈ¡Ëøʧ°ÜµÄ½Úµã£© 
  22.    if (shouldParkAfterFailedAcquire(p, node) && 
  23.     parkAndCheckInterrupt()) 
  24.     interrupted = true
  25.   } 
  26.  } finally { 
  27.   if (failed) 
  28.    cancelAcquire(node); 
  29.  } 

¸ù¾ÝÇ°¼Ì½ÚµãµÄ״̬£¬ÊÇ·ñ¿ÉÒÔ×èÈûµ±Ç°»ñÈ¡Ëøʧ°ÜµÄ½Úµã

Ò»°ãÇé¿ö»á¾­ÀúÈçÏÂ2¸ö¹ý³Ì

  1. ĬÈÏÇé¿öÏÂÉÏÒ»¸ö½ÚµãµÄwaitStatus=0£¬ËùÒÔ»á½øÈëcompareAndSetWaitStatus·½·¨£¬Í¨¹ýcas½«ÉÏÒ»¸ö½ÚµãµÄwaitStatusÉèÖÃΪSIGNAL£¬È»ºóreturn false
  2. shouldParkAfterFailedAcquire·½·¨ÍâÃæÊÇÒ»¸öËÀÑ­»·£¬µ±ÔٴνøÈëÕâ¸ö·½·¨Ê±£¬Èç¹ûÉÏÒ»²½cas³É¹¦£¬Ôò»á×ßµÚÒ»¸öif£¬return true¡£½Ó×ÅÖ´ÐÐparkAndCheckInterrupt£¬Ï̻߳á×èÈû
  1. private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { 
  2.  int ws = pred.waitStatus; 
  3.  // Ç°¼Ì½ÚµãÊÍ·Åʱ»áunparkºó¼Ì½Úµã£¬¿ÉÒÔ¹ÒÆð 
  4.  if (ws == Node.SIGNAL) 
  5.   return true
  6.  if (ws > 0) { 
  7.   //½«CANCELLED״̬µÄÏß³ÌÇåÀí³ö¶ÓÁР
  8.   // ºóÃæ»áÌᵽΪʲô»áÓÐCANCELLEDµÄ½Úµã 
  9.   do { 
  10.    node.prev = pred = pred.prev; 
  11.   } while (pred.waitStatus > 0); 
  12.   pred.next = node; 
  13.  } else { 
  14.   // ½«Ç°¼Ì½ÚµãµÄ״̬ÉèÖÃΪSIGNAL£¬´ú±íÊÍ·ÅËøʱÐèÒª»½ÐѺóÃæµÄÏ̠߳
  15.   // cas¸üпÉÄÜʧ°Ü£¬ËùÒÔ²»ÄÜÖ±½Ó·µ»Øtrue 
  16.   compareAndSetWaitStatus(pred, ws, Node.SIGNAL); 
  17.  } 
  18.  return false

shouldParkAfterFailedAcquire±íʾÉϺÃÄÖÖÓÁË£¬¿ÉÒÔ×èÈûÏß³ÌÁË¡£ºóÐøµ±Ï̱߳»»½ÐѵÄʱºò»á´ÓreturnÓï¾ä³ö¼ÌÐøÖ´ÐУ¬È»ºó½øÈëacquireQueued·½·¨µÄËÀÑ­»·£¬ÖØÐÂÇÀËø¡£ÖÁ´Ë£¬¼ÓËø½áÊø¡£

  1. // ¹ÒÆðỊ̈߳¬·µ»ØÊÇ·ñ±»ÖжϹý 
  2. private final boolean parkAndCheckInterrupt() { 
  3.  // ×èÈûÏ̠߳
  4.  LockSupport.park(this); 
  5.  // ·µ»Øµ±Ç°Ïß³ÌÊÇ·ñ±»µ÷ÓùýThread#interrupt·½·¨ 
  6.  return Thread.interrupted(); 

×îºóÓÃÒ»¸öÁ÷³ÌͼÀ´½âÊͲ»ÏìÓ¦ÖжϵĶÀÕ¼Ëø

Èë¶Ó¹ý³ÌÖÐÓÐÒì³£¸ÃÔõô°ì?

¿ÉÒÔ¿´µ½ÉÏÃæµ÷ÓÃacquireQueued·½·¨·¢ÉúÒì³£µÄʱºò£¬»áµ÷ÓÃcancelAcquire·½·¨£¬ÎÒÃǾÍÏêϸ·ÖÎöÒ»ÏÂÕâ¸öcancelAcquire·½·¨ÓÐÄÄЩ×÷ÓÃ?

¡¸ÄÄЩµØ·½Ö´Ðз¢ÉúÒì³£»áÖ´ÐÐcancelAcquire?¡¹

¿ÉÒÔ¿´µ½µ÷ÓÃcancelAcquire·½·¨µÄÓÐÈçϼ¸¸ö²¿·Ö

¡¸·ÖÎöÕâЩ·½·¨µÄµ÷Ó㬷¢ÏÖ»ù±¾¾ÍÊÇÈçÏÂ2¸öµØ·½»á·¢ÉúÒì³£¡¹

  1. ³¢ÊÔ»ñÈ¡ËøµÄ·½·¨ÈçtryAcquire£¬ÕâЩһ°ãÊǽ»¸ø×ÓÀàÀ´ÊµÏÖµÄ
  2. µ±Ïß³ÌÊDZ»µ÷ÓÃThread#interrupt·½·¨»½ÐÑ£¬Èç¹ûÒªÏìÓ¦Öжϣ¬»áÅ׳öInterruptedException

  1. //´¦ÀíÒì³£Í˳öµÄnode 
  2. private void cancelAcquire(Node node) { 
  3.  if (node == null
  4.   return
  5.  
  6.  // ÉèÖøýڵ㲻ÔÙ¹ØÁªÈκÎÏ̠߳
  7.  node.thread = null
  8.  
  9.  // Ìø¹ýCANCELLED½Úµã£¬ÕÒµ½Ò»¸öÓÐЧµÄÇ°¼Ì½Úµã 
  10.  Node pred = node.prev; 
  11.  while (pred.waitStatus > 0) 
  12.   node.prev = pred = pred.prev; 
  13.  
  14.  // »ñÈ¡¹ýÂ˺óµÄÓÐЧ½ÚµãµÄºó¼Ì½Úµã 
  15.  Node predNext = pred.next
  16.  
  17.  // ÉèÖÃ״̬ΪȡÏû 
  18.  node.waitStatus = Node.CANCELLED; 
  19.  
  20.  // case 1 
  21.  if (node == tail && compareAndSetTail(node, pred)) { 
  22.   compareAndSetNext(pred, predNext, null); 
  23.  } else { 
  24.   // case 2 
  25.   int ws; 
  26.   if (pred != head && 
  27.    ((ws = pred.waitStatus) == Node.SIGNAL || 
  28.     (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) && 
  29.    pred.thread != null) { 
  30.    Node next = node.next
  31.    if (next != null && next.waitStatus <= 0) 
  32.     compareAndSetNext(pred, predNext, next); 
  33.   } else { 
  34.    // case3 
  35.    unparkSuccessor(node); 
  36.   } 
  37.  
  38.   node.next = node; // help GC 
  39.  } 

½«node³ö¶ÓÓÐÈçÏÂÈýÖÖÇé¿ö

µ±Ç°½ÚµãÊÇtail

µ±Ç°½Úµã²»ÊÇheadµÄºó¼Ì½Úµã£¬Ò²²»ÊÇtail

µ±Ç°½ÚµãÊÇheadµÄºó¼Ì½Úµã

¡¸µ±Ç°½ÚµãÊÇtail¡¹

compareAndSetTail£¬½«tailÖ¸Ïòpred compareAndSetNext£¬½«predµÄnextÖ¸Ïònull£¬Ò²¾ÍÊǰѵ±Ç°½ÚµãÒƳö¶ÓÁÐ

ÔÚÕâÀï²åÈëͼƬÃèÊö

¡¸µ±Ç°½Úµã²»ÊÇheadµÄºó¼Ì½Úµã£¬Ò²²»ÊÇtail¡¹

ÕâÀォnodeµÄÇ°¼Ì½ÚµãµÄnextÖ¸ÏòÁËnodeµÄºó¼Ì½Úµã£¬¼´compareAndSetNext(pred, predNext, next)£¬¡¸×¢ÒâpredºÍnode½ÚµãÖмäÓпÉÄÜÓÐCANCELLEDµÄ½Úµã£¬ÅÂÂÒ¾Íû»­³öÀ´¡¹

¡¸µ±Ç°½ÚµãÊÇheadµÄºó¼Ì½Úµã¡¹

ûÓжԶÓÁнøÐвÙ×÷£¬Ö»ÊǽøÐÐheadºó¼Ì½ÚµãµÄ»½ÐѲÙ×÷(unparkSuccessor·½·¨£¬ºóÃæ»á·ÖÎöÕâ¸ö·½·¨)£¬ÒòΪ´ËʱËûÊÇheadµÄºó¼Ì½Úµã£¬»¹ÊÇÓпÉÄÜ»ñÈ¡µ½ËøµÄ£¬ËùÒÔ»½ÐÑËü³¢ÊÔ»ñÈ¡Ò»²¨Ëø£¬µ±Ôٴε÷Óõ½shouldParkAfterFailedAcquire(ÅжÏÊÇ·ñÓ¦¸Ã×èÈûµÄ·½·¨Ê±)»á°ÑCANCELLED״̬µÄ½Úµã´Ó¶ÓÁÐÖÐɾ³ý

¶ÀÕ¼ËøµÄÊÍ·Å

¶ÀÕ¼ËøÊÇÊÍ·ÅÆäʵ¾ÍÊÇÀûÓÃcas½«state-1£¬µ±state=0±íʾËø±»ÊÍ·Å£¬ÐèÒª½«×èÈû¶ÓÁÐÖеÄÏ̻߳½ÐÑ

  1. // µ÷ÓÃReentrantLock#unlock·½·¨Æäʵ¾ÍÊǵ÷ÓÃrelease(1) 
  2. public final boolean release(int arg) { 
  3.  // ³¢ÊÔÊÍ·ÅËø 
  4.  // µ±state=0£¬±íʾËø±»ÊÍ·Å£¬tryRelease·µ»Øtrue£¬´ËʱÐèÒª»½ÐÑ×èÈû¶ÓÁÐÖеÄÏ̠߳
  5.  if (tryRelease(arg)) { 
  6.   Node h = head; 
  7.   if (h != null && h.waitStatus != 0) 
  8.    unparkSuccessor(h); 
  9.   return true
  10.  } 
  11.  return false

¡¸tryRelease¼´¾ßÌåµÄ½âËøÂß¼­£¬ÐèÒª×ÓÀà×Ô¼ºÈ¥ÊµÏÖ¡¹

¡¸»½ÐÑͬ²½¶ÓÁÐÖеÄỊ̈߳¬¿ÉÒÔ¿´µ½Ç°Ãæ¼ÓÁËÅжÏh != null && h.waitStatus != 0¡¹

h = null£¬ËµÃ÷ͬ²½Í¬²½¶ÓÁÐÖÐûÓÐÊý¾Ý£¬Ôò²»ÐèÒª»½ÐÑ h = null && waitStatus = 0£¬Í¬²½¶ÓÁÐÊÇÓÐÁË£¬µ«ÊÇûÓÐÏ̸߳ø×Ô¼ºÉÏÄÖÖÓ£¬²»Óû½ÐÑ h != null && waitStatus < 0£¬ËµÃ÷Í·½Úµã±»ÈËÉÏÁËÄÖÖÓ£¬×Ô¼ºÐèÒª»½ÐÑ×èÈûµÄÏß³Ì h != null && waitStatus > 0£¬Í·½ÚµãÒòΪ·¢ÉúÒì³£±»ÉèÖÃΪȡÏû£¬µ«»¹Êǵû½ÐÑÏß³Ì

  1. private void unparkSuccessor(Node node) { 
  2.  
  3.  int ws = node.waitStatus; 
  4.  if (ws < 0) 
  5.   compareAndSetWaitStatus(node, ws, 0); 
  6.  
  7.  // Í·½áµãµÄÏÂÒ»¸ö½Úµã 
  8.  Node s = node.next
  9.  // Îª¿Õ»òÕß±»È¡Ïû 
  10.  if (s == null || s.waitStatus > 0) { 
  11.   s = null
  12.   // ´Ó¶ÓÁÐβ²¿ÏòÇ°±éÀúÕÒµ½×îÇ°ÃæµÄÒ»¸öwaitStatus<=0µÄ½Úµã 
  13.   for (Node t = tail; t != null && t != node; t = t.prev) 
  14.    if (t.waitStatus <= 0) 
  15.     s = t; 
  16.  } 
  17.  if (s != null
  18.   // »½Ðѽڵã,µ«²¢²»±íʾËü³ÖÓÐËø£¬Òª´Ó×èÈûµÄµØ·½¿ªÊ¼ÔËÐР
  19.   LockSupport.unpark(s.thread); 

¡¸ÎªÊ²Ã´Òª´ÓºóÏòÇ°ÕÒµÚÒ»¸ö·ÇCANCELLEDµÄ½ÚµãÄØ?¡¹

  1. private Node addWaiter(Node mode) { 
  2.     Node node = new Node(Thread.currentThread(), mode); 
  3.     // Try the fast path of enq; backup to full enq on failure 
  4.     Node pred = tail; 
  5.     if (pred != null) { 
  6.         node.prev = pred; 
  7.         if (compareAndSetTail(pred, node)) { 
  8.          // Ïß³ÌÔÚÕâÀï¹ÒÆðÁË 
  9.             pred.next = node; 
  10.             return node; 
  11.         } 
  12.     } 
  13.     enq(node); 
  14.     return node; 

ÕâÆäʵºÍÈë¶ÓµÄÂß¼­ÓйØϵ£¬¼ÙÈçNode1ÔÚͼʾλÖùÒÆðÁË£¬Node1ºóÃæÓÖ½ÐøÔö¼ÓÁËNode2ºÍNode3£¬Èç¹û´Ëʱ´ÓÇ°Ïòºó±éÀú»áµ¼ÖÂÔªËضªÊ§£¬²»ÄÜÕýÈ·»½ÐÑÏß³Ì

·ÖÎöһ϶ÀÕ¼ËøÏìÓ¦ÖжϺͲ»ÏìÓ¦ÖжϵÄÇø±ð

ÎÒÃÇ֮ǰ˵¹ý¶ÀÕ¼Ëø¿ÉÒÔÏìÓ¦Öжϣ¬Ò²¿ÉÒÔ²»ÏìÓ¦Öжϣ¬µ÷Óõķ½·¨ÈçÏÂ?

  1. ²»ÏìÓ¦ÖжϵĶÀÕ¼Ëø(acquire)
  2. ÏìÓ¦ÖжϵĶÀÕ¼Ëø(acquireInterruptibly)

ËùÒÔÎÒÃÇÖ»ÐèÒª¿´Õâ2¸ö·½·¨µÄÇø±ðÔÚÄÄÀï¾Í¿ÉÒÔ£¬ÎÒÏÂÃæÖ»ÁгöÓÐÇø±ðµÄ²¿·Ö¹þ¡£

  1. public final void acquire(int arg) { 
  2.     if (!tryAcquire(arg) && 
  3.         acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) 
  4.         selfInterrupt(); 
  1. public final void acquireInterruptibly(int arg) 
  2.         throws InterruptedException { 
  3.     // ÅжÏÏß³ÌÊÇ·ñ±»ÖжϠ
  4.     if (Thread.interrupted()) 
  5.         throw new InterruptedException(); 
  6.     if (!tryAcquire(arg)) 
  7.         doAcquireInterruptibly(arg); 

¡¸acquireÔÚ³¢ÊÔ»ñÈ¡ËøµÄʱºòÍêÈ«²»¹ÜÏß³ÌÓÐûÓб»Öжϣ¬¶øacquireInterruptiblyÔÚ³¢ÊÔ»ñÈ¡Ëø֮ǰ»áÅжÏÏß³ÌÊÇ·ñ±»Öжϣ¬Èç¹û±»Öжϣ¬ÔòÖ±½ÓÅ׳öÒì³£¡£¡¹

tryAcquire·½·¨Ò»Ñù£¬ËùÒÔÎÒÃÇÖ»ÐèÒª¶Ô±ÈacquireQueued·½·¨ºÍdoAcquireInterruptibly·½·¨µÄÇø±ð¼´¿É

¡¸Ö´ÐÐacquireQueued·½·¨µ±Ï̷߳¢ÉúÖжÏʱ£¬Ö»Êǽ«interruptedÉèÖÃΪtrue£¬²¢ÇÒµ÷ÓÃselfInterrupt·½·¨½«Öжϱê־λÉèÖÃΪtrue¡¹

¡¸¶øÖ´ÐÐdoAcquireInterruptibly·½·¨£¬µ±Ï̷߳¢ÉúÖжÏʱ£¬Ö±½ÓÅ׳öÒì³£¡£¡¹

×îºó¿´Ò»ÏÂparkAndCheckInterrupt·½·¨£¬Õâ¸ö·½·¨ÖÐÅжÏÏß³ÌÊÇ·ñÖжϵÄÂß¼­ÌرðÇÉ!

  1. private final boolean parkAndCheckInterrupt() { 
  2.  LockSupport.park(this); 
  3.  return Thread.interrupted(); 

¡¸ThreadÀàÌṩÁËÈçÏÂ2¸ö·½·¨À´ÅжÏÏß³ÌÊÇ·ñÊÇÖжÏ״̬¡¹

  1. isInterrupted
  2. interrupted

¡¸ÕâÀïΪʲôÓÃinterrupted¶ø²»ÊÇisInterruptedµÄÄØ?¡¹

ÑÝʾһÏÂÕâ2¸ö·½·¨µÄÇø±ð

  1. @Test 
  2. public void testInterrupt() throws InterruptedException { 
  3.     Thread thread = new Thread(() -> { 
  4.         while (true) {} 
  5.     }); 
  6.     thread.start(); 
  7.     TimeUnit.MICROSECONDS.sleep(100); 
  8.     thread.interrupt(); 
  9.     // true 
  10.     System.out.println(thread.isInterrupted()); 
  11.     // true 
  12.     System.out.println(thread.isInterrupted()); 
  13.     // true 
  14.     System.out.println(thread.isInterrupted()); 
  1. @Test 
  2. public void testInterrupt2() { 
  3.     Thread.currentThread().interrupt(); 
  4.     // true 
  5.     System.out.println(Thread.interrupted()); 
  6.     // false 
  7.     System.out.println(Thread.interrupted()); 
  8.     // false 
  9.     System.out.println(Thread.interrupted()); 

¡¸isInterruptedºÍinterruptedµÄ·½·¨Çø±ðÈçÏ¡¹

Thread#isInterrupted£º²âÊÔÏß³ÌÊÇ·ñÊÇÖжÏ״̬£¬Ö´Ðк󲻸ü¸Ä״̬±êÖ¾ Thread#interrupted£º²âÊÔÏß³ÌÊÇ·ñÊÇÖжÏ״̬£¬Ö´Ðкó½«ÖжϱêÖ¾¸ü¸ÄΪfalse

½Ó×ÅÔÙд2¸öÀý×Ó

  1. public static void main(String[] args) { 
  2.  LockSupport.park(); 
  3.  // end±»Ò»Ö±×èÈûûÓÐÊä³ö 
  4.  System.out.println("end"); 
  1. public static void main(String[] args) { 
  2.  Thread.currentThread().interrupt(); 
  3.  LockSupport.park(); 
  4.  // Êä³öend 
  5.  System.out.println("end"); 

¿ÉÒÔ¿´µ½µ±Ï̱߳»ÖжÏʱ£¬µ÷ÓÃpark()·½·¨²¢²»»á±»×èÈû

  1. public static void main(String[] args) { 
  2.  Thread.currentThread().interrupt(); 
  3.  LockSupport.park(); 
  4.  // ·µ»ØÖжÏ״̬£¬²¢ÇÒÇå³ýÖжÏ״̬ 
  5.  Thread.interrupted(); 
  6.  // Êä³östart 
  7.  System.out.println("start"); 
  8.  LockSupport.park(); 
  9.  // end±»×èÈû£¬Ã»ÓÐÊä³ö 
  10.  System.out.println("end"); 

µ½ÕâÎÒÃǾÍÄÜÀí½âΪʲôҪ½øÐÐÖжϵĸ´Î»ÁË

  • Èç¹ûµ±Ç°Ïß³ÌÊÇ·ÇÖжÏ״̬£¬ÔòÔÚÖ´ÐÐparkʱ±»×èÈû£¬·µ»ØÖжÏ״̬false
  • Èç¹ûµ±Ç°Ïß³ÌÊÇÖжÏ״̬£¬Ôòpark·½·¨²»Æð×÷Ó㬷µ»ØÖжÏ״̬true£¬interrupted½«Öжϸ´Î»£¬±äΪfalse
  • ÔÙ´ÎÖ´ÐÐÑ­»·µÄʱºò£¬Ç°Ò»²½ÒѾ­ÔÚÏ̵߳ÄÖжÏ״̬½øÐÐÁ˸´Î»£¬ÔòÔٴε÷ÓÃpark·½·¨Ê±»á×èÈû

¡¸ËùÒÔÕâÀïÒª¶ÔÖжϽøÐи´Î»£¬ÊÇΪÁ˲»ÈÃÑ­»·Ò»Ö±Ö´ÐУ¬Èõ±Ç°Ï߳̽øÈë×èÈû״̬£¬Èç¹û²»½øÐи´Î»£¬Ç°Ò»¸öÏß³ÌÔÚ»ñÈ¡ËøÖ®ºóÖ´ÐÐÁ˺ܺÄʱµÄ²Ù×÷£¬Äǵ±Ç°Ïß³ÌÆñ²»ÊÇÒªÒ»Ö±Ö´ÐÐËÀÑ­»·£¬Ôì³ÉCPUʹÓÃÂÊì­Éý?¡¹

¶ÀÕ¼ËøµÄ»ñÈ¡ºÍÊÍ·ÅÎÒÃÇÒѾ­¸ãÇå³þÁË£¬¹²ÏíËøµÄ»ñÈ¡ºÍÊÍ·ÅÎÒÃǷŵ½·ÖÎöCountDownLatchÔ´ÂëµÄÄÇÒ»½ÚÀ´·ÖÎö

»ùÓÚAQS×Ô¼ºÐ´Ò»¸öËø

Äã¿´AQSÒѾ­°ÑÈë¶Ó£¬³ö¶Ó£¬×èÈû£¬»½ÐѵIJÙ×÷¶¼·â×°ºÃÁË£¬µ±ÎÒÃÇÓÃAQSÀ´ÊµÏÖ×Ô¼ºµÄËøʱ£¬¾Í·Ç³£µÄ·½±ãÁË£¬Ö»ÐèÒªÖØд¼ÓËøºÍ½âËøµÄÂß¼­¼´¿É¡£ÎÒÕâÀïÑÝʾһ¸ö»ùÓÚAQSʵÏֵķÇÖØÈëµÄ»¥³âËø

  1. public class MyLock { 
  2.  
  3.     private final Sync sync; 
  4.  
  5.     public MyLock() { 
  6.         sync = new Sync(); 
  7.     } 
  8.  
  9.     public class Sync extends AbstractQueuedSynchronizer { 
  10.  
  11.         @Override 
  12.         protected boolean tryAcquire(int arg) { 
  13.             return compareAndSetState(0, arg); 
  14.         } 
  15.  
  16.         @Override 
  17.         protected boolean tryRelease(int arg) { 
  18.             setState(0); 
  19.             return true
  20.         } 
  21.  
  22.     } 
  23.  
  24.     public void lock() { 
  25.         sync.acquire(1); 
  26.     } 
  27.  
  28.     public void unLock() { 
  29.         sync.release(1); 
  30.     } 

±¾ÎÄתÔØ×Ô΢ÐŹ«Öںš¸JavaʶÌá¹£¬¿ÉÒÔͨ¹ýÒÔ϶þάÂë¹Ø×¢¡£×ªÔر¾ÎÄÇëÁªÏµJavaʶÌù«Öںš£


±¾ÎÄתÔØ×ÔÍøÂ磬ԭÎÄÁ´½Ó£ºhttps://mp.weixin.qq.com/s/uUAUGQ_WGHJzhJAyBmcWYg
±¾Õ¾²¿·ÖÄÚÈÝתÔØÓÚÍøÂ磬°æȨ¹éÔ­×÷ÕßËùÓУ¬×ªÔØ֮ĿµÄÔÚÓÚ´«²¥¸ü¶àÓÅÐã¼¼ÊõÄÚÈÝ£¬ÈçÓÐÇÖȨÇëÁªÏµQQ/΢ÐÅ£º153890879ɾ³ý£¬Ð»Ð»£¡

ÍƼöͼÎÄ

  • ÖÜÅÅÐÐ
  • ÔÂÅÅÐÐ
  • ×ÜÅÅÐÐ

Ëæ»úÍƼö