JUC half-day tour

AQS

  • Unsafe usage of the CAS to use a large amount of CLH, the first two parameters and this is xxOffset, rolled over to the users of fast hardware processing code is probably a question of memory alignment, the entire operation involved offset (dest) has two parts

    mov edx, dest
    .....
    cmpxchg dword ptr [edx], ecx   ;ecx寄存器放置exchange_value
  • Unsafe not for the average developer, checking up on your class loader is not null (native)

  • To mark what this sentence, which AbstractOwnableSynchronizeris stored with the exclusion of Threadmembers

    * You may also find the inherited methods from {@link
    * AbstractOwnableSynchronizer} useful to keep track of the thread
    * owning an exclusive synchronizer.  You are encouraged to use them
    * -- this enables monitoring and diagnostic tools to assist users in
    * determining which threads hold locks.
  • May the try to Acquire the Thread A IF IT IS First in at The Queue. (This is a FIFO mechanism)

  • CLH lock enqueue be atomic (source code using the CAS (new nodes, tail) alternative implementations) into only operation on "tail" , and the team is atomic Insertion a CLH queue requires a single atomic , dequeuing involves only updating the "head", but also need to address the successor in part to deal with possible cancellation due to timeouts and interrupts, all the information is used waitStatus volatile to represent, say cancel (timeout or interrupt) is 1, SIGNAL (current subsequent need to wake up, requires special attention, unpark its successor when it releases or cancels) -1, and -2 / -3 Condition relates to the design, the temporary holding described herein

  • Chain design prevfor handling cancel the operation, nextused to treat blocking operation, when needed wakeup came running down the next (which has a little checking backwards from the atomically updated "tail " when a node's successor appears to be null case of persistence )

  • nextWaiterAnd nextthere are some differences, the former is a simple Node, and the latter is volatile, it seems more than one kind of specific purposes, use is determined whether there is a shared / ExclusivenextWaiter == SHARED

  • stateAnd statusso what difference ah (The synchronization state. Good vague ah, presumably resource status reentrant design)

  • CLH queue has exclusive ( null) and share (a null Node()) has two modes of providing the base class and ReentranceLock Semaphore / CyclicBarrier thread communication tools like

  • CLH locks are normally used forspinlocks

  • A node is signalled when its predecessor releases.

  • enqueue operation is achieved through a doubly linked list of CAS, see line583: enq(curious established operating head of the queue is empty, probably a lazy design)

  • Why unpark need to traverse forward from the back, we need to look at atomic concurrent case, when CAStail for the new node, the next original tail does not point to a real tail, and prev to ensure that all node must be able to traverse to (again big brother to kneel, ignorant force for a long time orz)

    private Node enq(final Node node) {
            for (;;) {
                Node t = tail;
                if (t == null) { // Must initialize
                    if (compareAndSetHead(new Node()))
                        tail = head;
                } else {
                    node.prev = t; 
                    if (compareAndSetTail(t, node)) {
                        // 刚好发生意外 新的tail.prev肯定有了,但旧的tail.next还是null
                        t.next = node;
                        return t;
                    }
                }
            }
        }
    
    
    private void unparkSuccessor(Node node) {
        /*
         * If status is negative (i.e., possibly needing signal) try
         * to clear in anticipation of signalling.  It is OK if this
         * fails or if status is changed by waiting thread.
         */
        int ws = node.waitStatus;
        if (ws < 0)
            compareAndSetWaitStatus(node, ws, 0);
    
        /*
         * Thread to unpark is held in successor, which is normally
         * just the next node.  But if cancelled or apparently null,
         * traverse backwards from tail to find the actual
         * non-cancelled successor.
         */
        Node s = node.next;
        if (s == null || s.waitStatus > 0) {
            s = null;
            for (Node t = tail; t != null && t != node; t = t.prev)
                if (t.waitStatus <= 0)
                    s = t;
        }
        if (s != null)
            LockSupport.unpark(s.thread);
    }

Guess you like

Origin www.cnblogs.com/caturra/p/11258131.html