publicbooleanoffer(E e){ checkNotNull(e); final Node<E> newNode = new Node<E>(e);
for (Node<E> t = tail, p = t;;) { Node<E> q = p.next; if (q == null) {// 如果p是尾节点 if (p.casNext(null, newNode)) {// 把item加入队列,让newNode变成活节点 if (p != t) // hop two nodes at a time casTail(t, newNode); // 更新tail失败也没关系,因为tail仅仅用于优化性能,并不影响正确性 returntrue; } } elseif (p == q) // p==q意味着p已经是一个离群节点 p = (t != (t = tail)) ? t : head; // 首先我们一定过时了: // 如果t过时了,尝试从tail重连; // 如果t没过时,说明tail也过时了,从head重连。 else// Check for tail updates after two hops. p = (p != t && t != (t = tail)) ? t : q; // 写竞争失败了而已,把p往后挪就好了. } }
publicbooleanremove(Object o){ if (o != null) { Node<E> next, pred = null; for (Node<E> p = first(); p != null; pred = p, p = next) { boolean removed = false; E item = p.item; if (item != null) { if (!o.equals(item)) { next = succ(p); continue; } removed = p.casItem(item, null); }
next = succ(p); if (pred != null && next != null) // unlink pred.casNext(p, next); if (removed) returntrue; } } returnfalse; }
// 2. 进行平衡化: if (IsRed(h.Right) && !IsRed(h.Left)) h = RotateLeft(h); // 右边红节点 if (IsRed(h.left) && IsRed(h.Left.Left)) h = RotateRight(h); // 我个人理解的写法,连续红节点 // if (IsRed(h.Right) && IsRed(h.Left.Left)) h = RotateRight(h); // 原文写法,我感觉不对 if (IsRed(h.Left) && IsRed(h.Right)) h = FlipColor(h);// 颜色反转
/** * The array of bins. Lazily initialized upon first insertion. * Size is always a power of two. Accessed directly by iterators. */ transientvolatile Node<K,V>[] table;
/** * Base counter value, used mainly when there is no contention, * but also as a fallback during table initialization * races. Updated via CAS. */ privatetransientvolatilelong baseCount; privatetransientvolatileint sizeCtl;
/** * The next table index (plus one) to split while resizing. */ privatetransientvolatileint transferIndex;
/** * Spinlock (locked via CAS) used when resizing and/or creating CounterCells. */ privatetransientvolatileint cellsBusy;
/** * Table of counter cells. When non-null, size is a power of 2. */ privatetransientvolatile CounterCell[] counterCells;
/** * Nodes for use in TreeBins */ staticfinalclassTreeNode<K,V> extendsNode<K,V> { TreeNode<K,V> parent; // red-black tree links TreeNode<K,V> left; TreeNode<K,V> right; TreeNode<K,V> prev; // needed to unlink next upon deletion boolean red;
staticfinalclassTreeBin<K,V> extendsNode<K,V> { TreeNode<K,V> root; volatile TreeNode<K,V> first; volatile Thread waiter; volatileint lockState; // values for lockState staticfinalint WRITER = 1; // set while holding write lock staticfinalint WAITER = 2; // set when waiting for write lock staticfinalint READER = 4; // increment value for setting read lock /** * Acquires write lock for tree restructuring. 进行平衡梳理的时候,也会lockRoot */ privatefinalvoidlockRoot(){ if (!U.compareAndSwapInt(this, LOCKSTATE, 0, WRITER)) contendedLock(); // offload to separate method }
/** * Releases write lock for tree restructuring. */ privatefinalvoidunlockRoot(){ lockState = 0; } /** * Finds or adds a node. * @return null if added */ final TreeNode<K,V> putTreeVal(int h, K k, V v){
tabAt方法,获取i位置上的Node:
1 2 3
static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) { return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE); }
casTabAt方法,CAS设定i位置上的Node:
1 2 3 4
staticfinal <K,V> booleancasTabAt(Node<K,V>[] tab, int i, Node<K,V> c, Node<K,V> v){ return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v); }
setTabAt方法,直接设定i位置上的Node(已经占据锁的时候使用), 利用volatile:
1 2 3
static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) { U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v); }
@ReservedStackAccess protectedfinalbooleantryAcquire(int acquires){ Thread current = Thread.currentThread(); int c = getState(); int w = exclusiveCount(c); if (c != 0) { // (Note: if c != 0 and w == 0 then shared count != 0) if (w == 0 || current != getExclusiveOwnerThread()) returnfalse; if (w + exclusiveCount(acquires) > MAX_COUNT) thrownew Error("Maximum lock count exceeded"); // Reentrant acquire setState(c + acquires); returntrue; } if (writerShouldBlock() || !compareAndSetState(c, c + acquires)) returnfalse; setExclusiveOwnerThread(current); returntrue; }
@ReservedStackAccess protectedfinalbooleantryRelease(int releases){ if (!isHeldExclusively()) thrownew IllegalMonitorStateException(); int nextc = getState() - releases; boolean free = exclusiveCount(nextc) == 0; if (free) setExclusiveOwnerThread(null); setState(nextc); return free; }
@ReservedStackAccess protectedfinalinttryAcquireShared(int unused){ Thread current = Thread.currentThread(); int c = getState(); if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) return -1; int r = sharedCount(c); if (!readerShouldBlock() && r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)) { if (r == 0) { firstReader = current; firstReaderHoldCount = 1; } elseif (firstReader == current) { firstReaderHoldCount++; } else { HoldCounter rh = cachedHoldCounter; if (rh == null || rh.tid != LockSupport.getThreadId(current)) cachedHoldCounter = rh = readHolds.get(); elseif (rh.count == 0) readHolds.set(rh); rh.count++; } return1; } return fullTryAcquireShared(current); }
@ReservedStackAccess protectedfinalbooleantryReleaseShared(int unused){ Thread current = Thread.currentThread(); if (firstReader == current) { // assert firstReaderHoldCount > 0; if (firstReaderHoldCount == 1) firstReader = null; else firstReaderHoldCount--; } else { HoldCounter rh = cachedHoldCounter; if (rh == null || rh.tid != LockSupport.getThreadId(current)) rh = readHolds.get(); int count = rh.count; if (count <= 1) { readHolds.remove(); if (count <= 0) throw unmatchedUnlockException(); } --rh.count; } for (;;) { int c = getState(); int nextc = c - SHARED_UNIT; if (compareAndSetState(c, nextc)) // Releasing the read lock has no effect on readers, // but it may allow waiting writers to proceed if // both read and write locks are now free. return nextc == 0; } }
privatevoidunparkSuccessor(Node node){ int ws = node.waitStatus; if (ws < 0) node.compareAndSetWaitStatus(ws, 0); Node s = node.next; if (s == null || s.waitStatus > 0) { s = null; for (Node p = tail; p != node && p != null; p = p.prev) if (p.waitStatus <= 0) s = p; } if (s != null) LockSupport.unpark(s.thread); }
AQS在设计上是基于模版方法模式的抽象类。也就是说,我们需要新增一个子类继承AQS,然后重写上述第2类方法。而第1类和第3类方法,要么是private的无法继承,要么是final的无法重写。而第二类方法,如果没有重写,默认实现只有一行throw new UnsupportedOperationException();,调用的时候就会直接抛异常了。
privatestaticfinalclassSyncextendsAbstractQueuedSynchronizer{ Sync(int count) { if (count <= 0) { thrownew IllegalArgumentException("count must larger than 0"); } setState(count); }
@Override publicinttryAcquireShared(int reduceCount){ for (; ; ) { int current = getState(); int newCount = current - reduceCount; if (newCount < 0 || compareAndSetState(current, newCount)) { return newCount; } } }
@Override publicbooleantryReleaseShared(int returnCount){ for (; ; ) { int current = getState(); int newCount = current + returnCount; if (compareAndSetState(current, newCount)) { returntrue; } } }
select dt,city from t where dt>='2018-01-01'and dt<='2018-01-02' and city='beijing' -- 转化为=> select dt,city from t where dt in ('2018-01-01','2018-01-02') and city='beijing'
select * from locations where lat between38.03-degrees(0.0253) and38.03 + degree(0.0253) and lon between-78.48 - degrees(0.0253) and-78.48 + degrees(0.0253);
select * from locations where lat between38.03-degrees(0.0253) and38.03 + degree(0.0253) and lon between-78.48 - degrees(0.0253) and-78.48 + degrees(0.0253) -- 增加对于索引的利用: and lat_floor in (36,37,38,39,40) and lon_floor in (-80,-79,-78,-77);