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}