001/** 002 * @Title: ShareLock.java 003 * @Package net.gdface.worker 004 * @Description: TODO 005 * @author guyadong 006 * @date 2015å¹´6月10æ—¥ 上åˆ9:00:50 007 * @version V1.0 008 */ 009package net.gdface.utils; 010 011import java.util.concurrent.TimeUnit; 012import java.util.concurrent.locks.AbstractQueuedSynchronizer; 013import java.util.concurrent.locks.Condition; 014import java.util.concurrent.locks.Lock; 015 016/** 017 * 共享é”<br> 018 * 实现固定数目 {@link #maxShareCount} 的资æºå…±äº«é”,é™åˆ¶å¹¶å‘线程数目.<br> 019 * åŒä¸€ä¸ªçº¿ç¨‹å†…åµŒå¥—åŠ é”è§£é”,ä¸ä¼šé‡å¤è®¡æ•° 020 * @see Lock 021 * @see AbstractQueuedSynchronizer 022 * @author guyadong 023 * 024 */ 025public class ShareLock implements Lock { 026 private static final class Sync extends AbstractQueuedSynchronizer { 027 private static final long serialVersionUID = -3340303865224708218L; 028 /** 029 * çº¿ç¨‹åŠ é”计数 030 */ 031 private final ThreadLocal<Integer> threadLockCount=new ThreadLocal<Integer>(); 032 Sync(int count) { 033 if (count <= 0) { 034 throw new IllegalArgumentException("maxShareCount must large than zero."); 035 } 036 setState(count); 037 } 038 @Override 039 public int tryAcquireShared(int acquireCount) { 040 Integer tlc=threadLockCount.get(); 041 if (null == tlc) { 042 for (;;) { 043 int current = getState(); 044 int newCount = current - acquireCount; 045 if (newCount < 0) { 046 return newCount; 047 }else if (compareAndSetState(current, newCount)) { 048 threadLockCount.set(acquireCount); 049 return newCount; 050 } 051 } 052 }else{ 053 tlc+=acquireCount; 054 return getState(); 055 } 056 } 057 @Override 058 public boolean tryReleaseShared(int releaseCount) { 059 Integer tlc = threadLockCount.get(); 060 if(null == tlc || tlc <= 0) 061 throw new IllegalStateException("Error threadLockCount"); 062 if ((tlc -= releaseCount) > 0) { 063 return true; 064 } else { 065 if(tlc!=0) 066 throw new IllegalStateException("Error threadLockCount"); 067 for (;;) { 068 int current = getState(); 069 int newCount = current + releaseCount; 070 if (compareAndSetState(current, newCount)) { 071 threadLockCount.set(null); 072 return true; 073 } 074 } 075 } 076 } 077 } 078 /** 079 * å¯ç”¨èµ„æºè®¡æ•° 080 */ 081 private final int maxShareCount; 082 /** 083 * åŒæ¥å¯¹è±¡ 084 */ 085 private final Sync sync; 086 /** 087 * @param maxShareCount 最大å¯ç”¨èµ„æºè®¡æ•° 088 */ 089 public ShareLock(int maxShareCount) { 090 this.maxShareCount = maxShareCount; 091 this.sync = new Sync(this.maxShareCount); 092 } 093 @Override 094 public void lock() { 095 sync.acquireShared(1); 096 } 097 @Override 098 public void lockInterruptibly() throws InterruptedException { 099 sync.acquireSharedInterruptibly(1); 100 } 101 @Override 102 public Condition newCondition() { 103 //䏿”¯æŒè¯¥æ–¹æ³• 104 throw new UnsupportedOperationException(); 105 } 106 @Override 107 public boolean tryLock() { 108 return sync.tryAcquireShared(1) >= 0; 109 } 110 @Override 111 public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { 112 return sync.tryAcquireSharedNanos(1, unit.toNanos(time)); 113 } 114 115 @Override 116 public void unlock() { 117 sync.releaseShared(1); 118 } 119 /** 120 * @return maxShareCount 121 */ 122 public int getMaxShareCount() { 123 return maxShareCount; 124 } 125}