• Semaphore源码分析


    public class SemaphoreExample1 {
        private final static int threadCount = 20;
        public static void main(String[] args) throws Exception {
            ExecutorService exec = Executors1.newCachedThreadPool();
            final Semaphore1 semaphore = new Semaphore1(1);  //并发数是3,每3个3个打印
            for (int i = 0; i < 4; i++) {
                exec.execute(() -> {
                    try {
                        semaphore.acquire(); // 获取一个许可,多线程访问
                        System.out.println("咔咔咔咔咔咔扩扩扩扩扩扩扩");
                        semaphore.release(); // 释放一个许可,多线程访问
                    } catch (Exception e) {
                    }
                });
            }
            exec.shutdown();
        }
    }
    //共享锁,跟读写锁的读锁是一样的逻辑。
    public class Semaphore1 implements java.io.Serializable {
        private static final long serialVersionUID = -3222578661600680210L;
        private final Sync sync;
    
        abstract static class Sync extends AbstractQueuedSynchronizer1 {
            private static final long serialVersionUID = 1192457210091910933L;
    
            Sync(int permits) {
                setState(permits);//state
            }
    
            final int getPermits() {
                return getState();
            }
    
            final int nonfairTryAcquireShared(int acquires) {//获取许可,多线程
                for (;;) {//死循环,直到获取一个许可。只有在许可没了才去排队
                    int available = getState();
                    int remaining = available - acquires;//state减1
                    if (remaining < 0 || compareAndSetState(available, remaining))//,多线程
                        return remaining;
                }
            }
    
            protected final boolean tryReleaseShared(int releases) {//释放许可,多线程访问
                for (;;) {
                    int current = getState();
                    int next = current + releases;
                    if (next < current) // overflow
                        throw new Error("Maximum permit count exceeded");
                    if (compareAndSetState(current, next))//减一成功,别的线程就可以获取了。
                        return true;
                }
            }
    
            final void reducePermits(int reductions) {
                for (;;) {
                    int current = getState();
                    int next = current - reductions;
                    if (next > current) // underflow
                        throw new Error("Permit count underflow");
                    if (compareAndSetState(current, next))
                        return;
                }
            }
    
            final int drainPermits() {
                for (;;) {
                    int current = getState();
                    if (current == 0 || compareAndSetState(current, 0))
                        return current;
                }
            }
        }
    
        static final class NonfairSync extends Sync {
            private static final long serialVersionUID = -2694183684443567898L;
    
            NonfairSync(int permits) {
                super(permits);
            }
    
            protected int tryAcquireShared(int acquires) {//获取许可,多线程
                return nonfairTryAcquireShared(acquires);
            }
        }
    
        static final class FairSync extends Sync {
            private static final long serialVersionUID = 2014338818796000944L;
    
            FairSync(int permits) {
                super(permits);
            }
    
            protected int tryAcquireShared(int acquires) {//获取许可
                for (;;) {//死循环,直到获取一个许可。只有在许可没了才去排队
                    if (hasQueuedPredecessors())//要不要去排队
                        return -1;
                    int available = getState();
                    int remaining = available - acquires;
                    if (remaining < 0 || compareAndSetState(available, remaining))
                        return remaining;
                }
            }
        }
    
        public Semaphore1(int permits) {
            sync = new NonfairSync(permits);
        }
    
        public Semaphore1(int permits, boolean fair) {
            sync = fair ? new FairSync(permits) : new NonfairSync(permits);
        }
    
        public void acquire() throws InterruptedException {//多线程访问
            sync.acquireSharedInterruptibly(1);//获取共享锁
        }
    
        public void acquireUninterruptibly() throws InterruptedException {
            sync.acquireShared(1);
        }
    
        public boolean tryAcquire() {//没有获取许可的,就丢弃,不排队
            return sync.nonfairTryAcquireShared(1) >= 0;
        }
    
        public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException {
            return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
        }
    
        public void release() {//多线程访问
            sync.releaseShared(1);
        }
    
        public void acquire(int permits) throws InterruptedException {
            if (permits < 0) throw new IllegalArgumentException();
            sync.acquireSharedInterruptibly(permits);
        }
    
        public void acquireUninterruptibly(int permits) throws InterruptedException {
            if (permits < 0) throw new IllegalArgumentException();
            sync.acquireShared(permits);
        }
    
        public boolean tryAcquire(int permits) {
            if (permits < 0) throw new IllegalArgumentException();
            return sync.nonfairTryAcquireShared(permits) >= 0;
        }
    
        public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
            throws InterruptedException {
            if (permits < 0) throw new IllegalArgumentException();
            return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
        }
    
        public void release(int permits) {
            if (permits < 0) throw new IllegalArgumentException();
            sync.releaseShared(permits);
        }
    
        public int availablePermits() {
            return sync.getPermits();
        }
    
        public int drainPermits() {
            return sync.drainPermits();
        }
    
        protected void reducePermits(int reduction) {
            if (reduction < 0) throw new IllegalArgumentException();
            sync.reducePermits(reduction);
        }
    
        public boolean isFair() {
            return sync instanceof FairSync;
        }
    
        public final boolean hasQueuedThreads() {
            return sync.hasQueuedThreads();
        }
    
        public final int getQueueLength() {
            return sync.getQueueLength();
        }
    
        protected Collection<Thread> getQueuedThreads() {
            return sync.getQueuedThreads();
        }
    
        public String toString() {
            return super.toString() + "[Permits = " + sync.getPermits() + "]";
        }
    }
  • 相关阅读:
    域名解析 A记录 MX记录 CNAME记录 TTL
    在SQL Server Management Studio中还原数据库
    Intel 2200BG无线网卡在2003下的使用
    Javascript 如何得到input type="radio" 的值?
    建立自动备份的维护计划
    [zt]再谈QQ自动登陆器:提供C#源码下载(下)
    Ajax 和 XML: 借鉴最优秀的 Ajax 应用程序
    征服 Ajax 应用程序的安全威胁
    为FckEditor增加插件,添加自定义的功能按钮ToolBarButton
    开发端到端的 Ajax 应用程序,第 1 部分: 用一个场景设置 Ajax 环境
  • 原文地址:https://www.cnblogs.com/yaowen/p/11350979.html
Copyright © 2020-2023  润新知