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ÊÇÕâÑù×öµÄ
µ±AÏß³ÌÊÍ·ÅËø£¬»½ÐѶÓÁÐÖеÄBỊ̈߳¬AÏ̻߳á´Ó¶ÓÁÐÖÐɾ³ý
Ädzö¶ÓÕâ¸öÊÂÇéÓÉËÀ´×ö?ÊÇÓɱ»»½ÐѵÄÏß³ÌÀ´×ö£¬¼´BÏß³Ì
×èÈûºÍ»½ÐÑÏ̵߳÷ÓÃapi¼´¿É
- // ×èÈûÏß³Ì
- LockSupport.park(this)
- // »½ÐÑÏß³Ì
- LockSupport.unpark(this)
JUCÖеÄÐí¶à²¢·¢¹¤¾ßÀàReentrantLock£¬CountDownLatchµÈµÄʵÏÖ¶¼ÒÀÀµAbstractQueuedSynchronizer
AbstractQueuedSynchronizer¶¨ÒåÁËÒ»¸öËøʵÏÖµÄÄÚ²¿Á÷³Ì£¬¶øÈçºÎ¼ÓËøºÍ½âËøÔòÔÚ¸÷¸ö×ÓÀàÖÐʵÏÖ£¬µäÐ͵ÄÄ£°å·½·¨Ä£Ê½
AQSÄÚ²¿Î¬»¤ÁËÒ»¸öFIFOµÄ¶ÓÁÐ(µ×²ãʵÏÖ¾ÍÊÇË«ÏòÁ´±í)£¬Í¨¹ý¸Ã¶ÓÁÐÀ´ÊµÏÖÏ̵߳IJ¢·¢·ÃÎÊ¿ØÖÆ£¬¶ÓÁÐÖеÄÔªËØÊÇÒ»¸öNode½Úµã
- static final class Node {
- //±íʾµ±Ç°Ïß³ÌÒÔ¹²Ïíģʽ³ÖÓÐËø
- static final Node SHARED = new Node();
- //±íʾµ±Ç°Ïß³ÌÒÔ¶Àռģʽ³ÖÓÐËø
- static final Node EXCLUSIVE = null;
- static final int CANCELLED = 1;
- static final int SIGNAL = -1;
- static final int CONDITION = -2;
- static final int PROPAGATE = -3;
- //µ±Ç°½ÚµãµÄ״̬
- volatile int waitStatus;
- //Ç°¼Ì½Úµã
- volatile Node prev;
- //ºó¼Ì½Úµã
- volatile Node next;
- //µ±Ç°Ïß³Ì
- volatile Thread thread;
- //´æ´¢ÔÚcondition¶ÓÁÐÖеĺó¼Ì½Úµã
- Node nextWaiter;
- }
waitStatus(ĬÈÏÊÇ0)±íʾ½ÚµãµÄ״̬£¬°üº¬µÄ״̬ÓÐ
״̬ | Öµ | º¬Òå |
---|---|---|
CANCELLED | 1 | Ï̻߳ñÈ¡ËøµÄÇëÇóÒѾȡÏû |
SIGNAL | -1 | ±íʾµ±Ç°½ÚµãµÄµÄºó¼Ì½Úµã½«Òª»òÕßÒѾ±»×èÈû£¬ÔÚµ±Ç°½ÚµãÊͷŵÄʱºòÐèÒªunparkºó¼Ì½Úµã |
CONDITION | -2 | ±íʾµ±Ç°½ÚµãÔڵȴýcondition£¬¼´ÔÚcondition¶ÓÁÐÖÐ |
PROPAGATE | -3 | ±íʾ״̬ÐèÒªÏòºó´«²¥£¬½öÔÚ¹²ÏíģʽÏÂʹÓã© |
0 | Node±»³õʼ»¯ºóµÄĬÈÏÖµ£¬µ±Ç°½ÚµãÔÚ¶ÓÁÐÖеȴý»ñÈ¡Ëø |
ÔÙÀ´¿´AbstractQueuedSynchronizerÕâ¸öÀàµÄÊôÐÔ
- //µÈ´ý¶ÓÁеÄÍ·½Úµã
- private transient volatile Node head;
- //µÈ´ý¶ÓÁеÄβ½Úµã
- private transient volatile Node tail;
- //¼ÓËøµÄ״̬£¬ÔÚ²»Í¬×ÓÀàÖÐÓв»Í¬µÄÒâÒå
- 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µÄËø¿ÉÒÔ·ÖΪÈçÏÂËÄÀà
¶øÊÍ·ÅËøµÄ·½Ê½Ö»ÓÐÁ½ÖÖ
ÒÔReentrantLockΪÀý£¬´Ó¼ÓËøÕâÒ»²¿·Ö¿ªÊ¼·ÖÎö
- // µ÷ÓÃReentrantLock.FairSync#lock·½·¨Æäʵ¾ÍÊǵ÷ÓÃacquire(1);
- public final void acquire(int arg) {
- if (!tryAcquire(arg) &&
- acquireQueued(addWaiter(Node.EXCLUSIVE), arg))//»ñÈ¡µ½Ëø·µ»Øfalse£¬·ñÔò·µ»Øtrue
- selfInterrupt();//µ±Ç°Ï߳̽«×Ô¼ºÖжÏ
- }
¡¸´Ó´úÂë²ãÃæÏêϸ·ÖÎöÒ»²¨£¬×ßÆð¡¹
tryAcquireÊÇÈÃ×ÓÀàʵÏÖµÄ
- protected boolean tryAcquire(int arg) {
- throw new UnsupportedOperationException();
- }
ÕâÀïͨ¹ýÅ׳öÒì³£À´¸æËß×ÓÀàÒªÖØдÕâ¸ö·½·¨£¬ÎªÊ²Ã´²»½«Õâ¸ö·½·¨¶¨ÒåΪabstract·½·¨ÄØ?ÒòΪAQSÓÐ2ÖÖ¹¦ÄÜ£¬¶ÀÕ¼ºÍ¹²Ïí£¬Èç¹ûÓÃabstractÐÞÊΣ¬Ôò×ÓÀàÐèҪͬʱʵÏÖÁ½ÖÖ¹¦Äܵķ½·¨£¬¶Ô×ÓÀ಻ÓѺÃ
- private Node addWaiter(Node mode) {
- Node node = new Node(Thread.currentThread(), mode);
- Node pred = tail;
- if (pred != null) {
- node.prev = pred;
- if (compareAndSetTail(pred, node)) {
- pred.next = node;
- return node;
- }
- }
- enq(node);
- return node;
- }
¡¸Ç°ÃæÒѾ˵¹ýÁ˹þ£¬AQS¶ÓÁÐΪ¿Õʱ£¬µÚÒ»´Î»á·ÅÈë2¸ö½Úµã¡¹
- private Node enq(final Node node) {
- for (;;) {
- Node t = tail;
- // ¶ÓÁÐΪ¿Õ£¬½øÐгõʼ»¯£¬
- if (t == null) {
- if (compareAndSetHead(new Node()))
- tail = head;
- } else {
- node.prev = t;
- if (compareAndSetTail(t, node)) {
- t.next = node;
- return t;
- }
- }
- }
- }
·ÅÈë¶ÓÁкó»¹Òª¸Éʲô?
- // ×ÔÐý»ñÈ¡Ëø£¬Ö±µ½»ñÈ¡Ëø³É¹¦£¬»òÕßÒì³£Í˳ö
- // µ«ÊDz¢²»ÊÇbusy acquire£¬ÒòΪµ±»ñȡʧ°Üºó»á±»¹ÒÆð£¬ÓÉÇ°Çý½ÚµãÊÍ·ÅËøʱ½«Æ份ÐÑ
- // ͬʱÓÉÓÚ»½ÐѵÄʱºò¿ÉÄÜÓÐÆäËûÏ߳̾ºÕù£¬ËùÒÔ»¹ÐèÒª½øÐг¢ÊÔ»ñÈ¡Ëø£¬ÌåÏֵķǹ«Æ½ËøµÄ¾«Ëè¡£
- final boolean acquireQueued(final Node node, int arg) {
- boolean failed = true;
- try {
- boolean interrupted = false;
- for (;;) {
- // »ñÈ¡Ç°¼Ì½Úµã
- final Node p = node.predecessor();
- // node½ÚµãµÄÇ°¼Ì½ÚµãÊÇhead½Úµã£¬³¢ÊÔ»ñÈ¡Ëø£¬Èç¹û³É¹¦ËµÃ÷head½ÚµãÒѾÊÍ·ÅËøÁË
- // ½«nodeÉèΪhead¿ªÊ¼ÔËÐÐ(headÖв»°üº¬thread)
- if (p == head && tryAcquire(arg)) {
- setHead(node);
- // ½«µÚÒ»¸ö½Úµã³ö¶Ó
- p.next = null; // help GC
- failed = false;
- return interrupted;
- }
- // »ñÈ¡Ëøʧ°ÜºóÊÇ·ñ¿ÉÒÔ¹ÒÆð
- // Èç¹û¿ÉÒÔ¹ÒÆð£¬Ôò×èÈûµ±Ç°Ị̈߳¨»ñÈ¡Ëøʧ°ÜµÄ½Úµã£©
- if (shouldParkAfterFailedAcquire(p, node) &&
- parkAndCheckInterrupt())
- interrupted = true;
- }
- } finally {
- if (failed)
- cancelAcquire(node);
- }
- }
¸ù¾ÝÇ°¼Ì½ÚµãµÄ״̬£¬ÊÇ·ñ¿ÉÒÔ×èÈûµ±Ç°»ñÈ¡Ëøʧ°ÜµÄ½Úµã
Ò»°ãÇé¿ö»á¾ÀúÈçÏÂ2¸ö¹ý³Ì
- private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
- int ws = pred.waitStatus;
- // Ç°¼Ì½ÚµãÊÍ·Åʱ»áunparkºó¼Ì½Úµã£¬¿ÉÒÔ¹ÒÆð
- if (ws == Node.SIGNAL)
- return true;
- if (ws > 0) {
- //½«CANCELLED״̬µÄÏß³ÌÇåÀí³ö¶ÓÁÐ
- // ºóÃæ»áÌᵽΪʲô»áÓÐCANCELLEDµÄ½Úµã
- do {
- node.prev = pred = pred.prev;
- } while (pred.waitStatus > 0);
- pred.next = node;
- } else {
- // ½«Ç°¼Ì½ÚµãµÄ״̬ÉèÖÃΪSIGNAL£¬´ú±íÊÍ·ÅËøʱÐèÒª»½ÐѺóÃæµÄÏß³Ì
- // cas¸üпÉÄÜʧ°Ü£¬ËùÒÔ²»ÄÜÖ±½Ó·µ»Øtrue
- compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
- }
- return false;
- }
shouldParkAfterFailedAcquire±íʾÉϺÃÄÖÖÓÁË£¬¿ÉÒÔ×èÈûÏß³ÌÁË¡£ºóÐøµ±Ï̱߳»»½ÐѵÄʱºò»á´ÓreturnÓï¾ä³ö¼ÌÐøÖ´ÐУ¬È»ºó½øÈëacquireQueued·½·¨µÄËÀÑ»·£¬ÖØÐÂÇÀËø¡£ÖÁ´Ë£¬¼ÓËø½áÊø¡£
- // ¹ÒÆðỊ̈߳¬·µ»ØÊÇ·ñ±»ÖжϹý
- private final boolean parkAndCheckInterrupt() {
- // ×èÈûÏß³Ì
- LockSupport.park(this);
- // ·µ»Øµ±Ç°Ïß³ÌÊÇ·ñ±»µ÷ÓùýThread#interrupt·½·¨
- return Thread.interrupted();
- }
×îºóÓÃÒ»¸öÁ÷³ÌͼÀ´½âÊͲ»ÏìÓ¦ÖжϵĶÀÕ¼Ëø
¿ÉÒÔ¿´µ½ÉÏÃæµ÷ÓÃacquireQueued·½·¨·¢ÉúÒì³£µÄʱºò£¬»áµ÷ÓÃcancelAcquire·½·¨£¬ÎÒÃǾÍÏêϸ·ÖÎöÒ»ÏÂÕâ¸öcancelAcquire·½·¨ÓÐÄÄЩ×÷ÓÃ?
¡¸ÄÄЩµØ·½Ö´Ðз¢ÉúÒì³£»áÖ´ÐÐcancelAcquire?¡¹
¿ÉÒÔ¿´µ½µ÷ÓÃcancelAcquire·½·¨µÄÓÐÈçϼ¸¸ö²¿·Ö
¡¸·ÖÎöÕâЩ·½·¨µÄµ÷Ó㬷¢ÏÖ»ù±¾¾ÍÊÇÈçÏÂ2¸öµØ·½»á·¢ÉúÒì³£¡¹
- //´¦ÀíÒì³£Í˳öµÄnode
- private void cancelAcquire(Node node) {
- if (node == null)
- return;
- // ÉèÖøýڵ㲻ÔÙ¹ØÁªÈκÎÏß³Ì
- node.thread = null;
- // Ìø¹ýCANCELLED½Úµã£¬ÕÒµ½Ò»¸öÓÐЧµÄÇ°¼Ì½Úµã
- Node pred = node.prev;
- while (pred.waitStatus > 0)
- node.prev = pred = pred.prev;
- // »ñÈ¡¹ýÂ˺óµÄÓÐЧ½ÚµãµÄºó¼Ì½Úµã
- Node predNext = pred.next;
- // ÉèÖÃ״̬ΪȡÏû
- node.waitStatus = Node.CANCELLED;
- // case 1
- if (node == tail && compareAndSetTail(node, pred)) {
- compareAndSetNext(pred, predNext, null);
- } else {
- // case 2
- int ws;
- if (pred != head &&
- ((ws = pred.waitStatus) == Node.SIGNAL ||
- (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
- pred.thread != null) {
- Node next = node.next;
- if (next != null && next.waitStatus <= 0)
- compareAndSetNext(pred, predNext, next);
- } else {
- // case3
- unparkSuccessor(node);
- }
- node.next = node; // help GC
- }
- }
½«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±íʾËø±»ÊÍ·Å£¬ÐèÒª½«×èÈû¶ÓÁÐÖеÄÏ̻߳½ÐÑ
- // µ÷ÓÃReentrantLock#unlock·½·¨Æäʵ¾ÍÊǵ÷ÓÃrelease(1)
- public final boolean release(int arg) {
- // ³¢ÊÔÊÍ·ÅËø
- // µ±state=0£¬±íʾËø±»ÊÍ·Å£¬tryRelease·µ»Øtrue£¬´ËʱÐèÒª»½ÐÑ×èÈû¶ÓÁÐÖеÄÏß³Ì
- if (tryRelease(arg)) {
- Node h = head;
- if (h != null && h.waitStatus != 0)
- unparkSuccessor(h);
- return true;
- }
- return false;
- }
¡¸tryRelease¼´¾ßÌåµÄ½âËøÂß¼£¬ÐèÒª×ÓÀà×Ô¼ºÈ¥ÊµÏÖ¡¹
¡¸»½ÐÑͬ²½¶ÓÁÐÖеÄỊ̈߳¬¿ÉÒÔ¿´µ½Ç°Ãæ¼ÓÁËÅжÏh != null && h.waitStatus != 0¡¹
h = null£¬ËµÃ÷ͬ²½Í¬²½¶ÓÁÐÖÐûÓÐÊý¾Ý£¬Ôò²»ÐèÒª»½ÐÑ h = null && waitStatus = 0£¬Í¬²½¶ÓÁÐÊÇÓÐÁË£¬µ«ÊÇûÓÐÏ̸߳ø×Ô¼ºÉÏÄÖÖÓ£¬²»Óû½ÐÑ h != null && waitStatus < 0£¬ËµÃ÷Í·½Úµã±»ÈËÉÏÁËÄÖÖÓ£¬×Ô¼ºÐèÒª»½ÐÑ×èÈûµÄÏß³Ì h != null && waitStatus > 0£¬Í·½ÚµãÒòΪ·¢ÉúÒì³£±»ÉèÖÃΪȡÏû£¬µ«»¹Êǵû½ÐÑÏß³Ì
- private void unparkSuccessor(Node node) {
- int ws = node.waitStatus;
- if (ws < 0)
- compareAndSetWaitStatus(node, ws, 0);
- // Í·½áµãµÄÏÂÒ»¸ö½Úµã
- Node s = node.next;
- // Ϊ¿Õ»òÕß±»È¡Ïû
- if (s == null || s.waitStatus > 0) {
- s = null;
- // ´Ó¶ÓÁÐβ²¿ÏòÇ°±éÀúÕÒµ½×îÇ°ÃæµÄÒ»¸öwaitStatus<=0µÄ½Úµã
- for (Node t = tail; t != null && t != node; t = t.prev)
- if (t.waitStatus <= 0)
- s = t;
- }
- if (s != null)
- // »½Ðѽڵã,µ«²¢²»±íʾËü³ÖÓÐËø£¬Òª´Ó×èÈûµÄµØ·½¿ªÊ¼ÔËÐÐ
- LockSupport.unpark(s.thread);
- }
¡¸ÎªÊ²Ã´Òª´ÓºóÏòÇ°ÕÒµÚÒ»¸ö·ÇCANCELLEDµÄ½ÚµãÄØ?¡¹
- private Node addWaiter(Node mode) {
- Node node = new Node(Thread.currentThread(), mode);
- // Try the fast path of enq; backup to full enq on failure
- Node pred = tail;
- if (pred != null) {
- node.prev = pred;
- if (compareAndSetTail(pred, node)) {
- // Ïß³ÌÔÚÕâÀï¹ÒÆðÁË
- pred.next = node;
- return node;
- }
- }
- enq(node);
- return node;
- }
ÕâÆäʵºÍÈë¶ÓµÄÂß¼ÓйØϵ£¬¼ÙÈçNode1ÔÚͼʾλÖùÒÆðÁË£¬Node1ºóÃæÓÖ½ÐøÔö¼ÓÁËNode2ºÍNode3£¬Èç¹û´Ëʱ´ÓÇ°Ïòºó±éÀú»áµ¼ÖÂÔªËضªÊ§£¬²»ÄÜÕýÈ·»½ÐÑÏß³Ì
·ÖÎöһ϶ÀÕ¼ËøÏìÓ¦ÖжϺͲ»ÏìÓ¦ÖжϵÄÇø±ð
ÎÒÃÇ֮ǰ˵¹ý¶ÀÕ¼Ëø¿ÉÒÔÏìÓ¦Öжϣ¬Ò²¿ÉÒÔ²»ÏìÓ¦Öжϣ¬µ÷Óõķ½·¨ÈçÏÂ?
ËùÒÔÎÒÃÇÖ»ÐèÒª¿´Õâ2¸ö·½·¨µÄÇø±ðÔÚÄÄÀï¾Í¿ÉÒÔ£¬ÎÒÏÂÃæÖ»ÁгöÓÐÇø±ðµÄ²¿·Ö¹þ¡£
- public final void acquire(int arg) {
- if (!tryAcquire(arg) &&
- acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
- selfInterrupt();
- }
- public final void acquireInterruptibly(int arg)
- throws InterruptedException {
- // ÅжÏÏß³ÌÊÇ·ñ±»ÖжÏ
- if (Thread.interrupted())
- throw new InterruptedException();
- if (!tryAcquire(arg))
- doAcquireInterruptibly(arg);
- }
¡¸acquireÔÚ³¢ÊÔ»ñÈ¡ËøµÄʱºòÍêÈ«²»¹ÜÏß³ÌÓÐûÓб»Öжϣ¬¶øacquireInterruptiblyÔÚ³¢ÊÔ»ñÈ¡Ëø֮ǰ»áÅжÏÏß³ÌÊÇ·ñ±»Öжϣ¬Èç¹û±»Öжϣ¬ÔòÖ±½ÓÅ׳öÒì³£¡£¡¹
tryAcquire·½·¨Ò»Ñù£¬ËùÒÔÎÒÃÇÖ»ÐèÒª¶Ô±ÈacquireQueued·½·¨ºÍdoAcquireInterruptibly·½·¨µÄÇø±ð¼´¿É
¡¸Ö´ÐÐacquireQueued·½·¨µ±Ï̷߳¢ÉúÖжÏʱ£¬Ö»Êǽ«interruptedÉèÖÃΪtrue£¬²¢ÇÒµ÷ÓÃselfInterrupt·½·¨½«Öжϱê־λÉèÖÃΪtrue¡¹
¡¸¶øÖ´ÐÐdoAcquireInterruptibly·½·¨£¬µ±Ï̷߳¢ÉúÖжÏʱ£¬Ö±½ÓÅ׳öÒì³£¡£¡¹
×îºó¿´Ò»ÏÂparkAndCheckInterrupt·½·¨£¬Õâ¸ö·½·¨ÖÐÅжÏÏß³ÌÊÇ·ñÖжϵÄÂß¼ÌرðÇÉ!
- private final boolean parkAndCheckInterrupt() {
- LockSupport.park(this);
- return Thread.interrupted();
- }
¡¸ThreadÀàÌṩÁËÈçÏÂ2¸ö·½·¨À´ÅжÏÏß³ÌÊÇ·ñÊÇÖжÏ״̬¡¹
¡¸ÕâÀïΪʲôÓÃinterrupted¶ø²»ÊÇisInterruptedµÄÄØ?¡¹
ÑÝʾһÏÂÕâ2¸ö·½·¨µÄÇø±ð
- @Test
- public void testInterrupt() throws InterruptedException {
- Thread thread = new Thread(() -> {
- while (true) {}
- });
- thread.start();
- TimeUnit.MICROSECONDS.sleep(100);
- thread.interrupt();
- // true
- System.out.println(thread.isInterrupted());
- // true
- System.out.println(thread.isInterrupted());
- // true
- System.out.println(thread.isInterrupted());
- }
- @Test
- public void testInterrupt2() {
- Thread.currentThread().interrupt();
- // true
- System.out.println(Thread.interrupted());
- // false
- System.out.println(Thread.interrupted());
- // false
- System.out.println(Thread.interrupted());
- }
¡¸isInterruptedºÍinterruptedµÄ·½·¨Çø±ðÈçÏ¡¹
Thread#isInterrupted£º²âÊÔÏß³ÌÊÇ·ñÊÇÖжÏ״̬£¬Ö´Ðк󲻸ü¸Ä״̬±êÖ¾ Thread#interrupted£º²âÊÔÏß³ÌÊÇ·ñÊÇÖжÏ״̬£¬Ö´Ðкó½«ÖжϱêÖ¾¸ü¸ÄΪfalse
½Ó×ÅÔÙд2¸öÀý×Ó
- public static void main(String[] args) {
- LockSupport.park();
- // end±»Ò»Ö±×èÈûûÓÐÊä³ö
- System.out.println("end");
- }
- public static void main(String[] args) {
- Thread.currentThread().interrupt();
- LockSupport.park();
- // Êä³öend
- System.out.println("end");
- }
¿ÉÒÔ¿´µ½µ±Ï̱߳»ÖжÏʱ£¬µ÷ÓÃpark()·½·¨²¢²»»á±»×èÈû
- public static void main(String[] args) {
- Thread.currentThread().interrupt();
- LockSupport.park();
- // ·µ»ØÖжÏ״̬£¬²¢ÇÒÇå³ýÖжÏ״̬
- Thread.interrupted();
- // Êä³östart
- System.out.println("start");
- LockSupport.park();
- // end±»×èÈû£¬Ã»ÓÐÊä³ö
- System.out.println("end");
- }
µ½ÕâÎÒÃǾÍÄÜÀí½âΪʲôҪ½øÐÐÖжϵĸ´Î»ÁË
¡¸ËùÒÔÕâÀïÒª¶ÔÖжϽøÐи´Î»£¬ÊÇΪÁ˲»ÈÃÑ»·Ò»Ö±Ö´ÐУ¬Èõ±Ç°Ï߳̽øÈë×èÈû״̬£¬Èç¹û²»½øÐи´Î»£¬Ç°Ò»¸öÏß³ÌÔÚ»ñÈ¡ËøÖ®ºóÖ´ÐÐÁ˺ܺÄʱµÄ²Ù×÷£¬Äǵ±Ç°Ïß³ÌÆñ²»ÊÇÒªÒ»Ö±Ö´ÐÐËÀÑ»·£¬Ôì³ÉCPUʹÓÃÂÊìÉý?¡¹
¶ÀÕ¼ËøµÄ»ñÈ¡ºÍÊÍ·ÅÎÒÃÇÒѾ¸ãÇå³þÁË£¬¹²ÏíËøµÄ»ñÈ¡ºÍÊÍ·ÅÎÒÃǷŵ½·ÖÎöCountDownLatchÔ´ÂëµÄÄÇÒ»½ÚÀ´·ÖÎö
Äã¿´AQSÒѾ°ÑÈë¶Ó£¬³ö¶Ó£¬×èÈû£¬»½ÐѵIJÙ×÷¶¼·â×°ºÃÁË£¬µ±ÎÒÃÇÓÃAQSÀ´ÊµÏÖ×Ô¼ºµÄËøʱ£¬¾Í·Ç³£µÄ·½±ãÁË£¬Ö»ÐèÒªÖØд¼ÓËøºÍ½âËøµÄÂß¼¼´¿É¡£ÎÒÕâÀïÑÝʾһ¸ö»ùÓÚAQSʵÏֵķÇÖØÈëµÄ»¥³âËø
- public class MyLock {
- private final Sync sync;
- public MyLock() {
- sync = new Sync();
- }
- public class Sync extends AbstractQueuedSynchronizer {
- @Override
- protected boolean tryAcquire(int arg) {
- return compareAndSetState(0, arg);
- }
- @Override
- protected boolean tryRelease(int arg) {
- setState(0);
- return true;
- }
- }
- public void lock() {
- sync.acquire(1);
- }
- public void unLock() {
- sync.release(1);
- }
- }
±¾ÎÄתÔØ×Ô΢ÐŹ«Öںš¸JavaʶÌá¹£¬¿ÉÒÔͨ¹ýÒÔ϶þάÂë¹Ø×¢¡£×ªÔر¾ÎÄÇëÁªÏµJavaʶÌù«Öںš£
XSS ¹¥»÷ xxs ¹¥»÷Ó¢ÎÄÈ«³ÆÊÇ Croess SiteScripting £¬Òâ˼¾ÍÊÇ¿çÕ¾½Å±¾¹¥»÷¡£ÊÇ...
±¾ÎÄתÔØ×Ô΢ÐŹ«Öںš¸³ÌÐòÐÂÊӽ硹£¬×÷Õ߶þʦÐÖ¡£×ªÔر¾ÎÄÇëÁªÏµ³ÌÐòÐÂÊӽ繫...
ÖÐÎÄ ÓòÃû Äܱ¸°¸Âð£¿Äܵģ¬Ä¿Ç°ÒÔÏÂÕâЩÓòÃû¶¼ÊÇÖ§³Ö±¸°¸µÄ£¬´ó¼ÒÔÚ×¢²áµÄʱºò...
Ò»¡¢Ç°ÑÔ ´ó¼ÒºÃ£¬ÎÒÊÇ´ÞÑÞ·É¡£¹¤×÷Öо³£»áÓöµ½£¬ÐèÒª°ÑÁ½ÕÅExcel»òCsvÊý¾Ý±íͨ...
Ô¶ÔÚ±±¼«µÄÊÀ½çÄ©ÈÕÖÖ×Ó¿â(The Svalbard Doomsday Seed Vault)ÖУ¬´æ´¢×Å°ÙÍòÖÖ...
ÄÄÀﹺÂò ÓòÃû ÐԼ۱Ⱥ㿹ºÂòÓòÃûÐԼ۱ȸߵģ¬Í¨³£ÊÇÔÚ ÓòÃû×¢²á ·þÎñÉÌ´¦Ö±½Ó ...
?¿Í»§¹Ø¼ü´Ê£º¹úÄÚÍ·²¿Ö±²¥Æ½Ì¨Ö®Ò»/ÒÚ¼¶ÈÕ»î²úÆ·/ÊýÊ®ÍòÖ±²¥´´×÷Õß Ö±²¥£¬×÷Ϊ...
ΪÁ˶Ô2021ÄêµÄÖØÒªÐÂÇ÷ÊÆÓÐËùÁ˽⣬ÐÐҵýÌå²É·ÃÁ˸÷ÐÐÒµ³§É̵ĸ߹ܣ¬ÒÔ»ñÈ¡Ëû...
ÌåÑéƪ ±¾ÎĽéÉܵÄÊÇunityÖнÓÈëÓÎÏ·¶àýÌåÒýÇæ. Ê×ÏÈ,ʲôÊÇÓÎÏ·¶àýÌåÒýÇæÄØ? ...
1£®ÊýѧÎÞÁĵ½Á¬¸öÈý½ÇÐζ¼ÒªÖ¤Ã÷£¬Âò¸ö²Ë¶¼ÒªÉèX¡£ 2£®Ã¿¸ö°ÑÊÖ²åÔÚ¶µÀïµÄÈË£¬...