java多线程系列9-共享锁Semaphore源码解析

锁系列文章
java多线程系列7-AbstractQueuedSynchronizer源码分析
java多线程系列8-ReentrantLock源码分析
java多线程系列10-读写锁ReentrantReadWriteLock源码分析

1.Semaphore介绍

Semaphore其实在前面并发工具类中介绍过。Semaphore初始化时会设值许可证的数量,即state的值。当有个线程尝试获取锁时,会尝试更新state的值,一般是将state的值减一。如果成功,则获得锁成功。如果state的值减到0时,后续线程获得锁将会加入队列等待。
Semaphore也会分为公平锁和非公平锁。
先看下构造方法:

  public Semaphore(int permits) {
        sync = new NonfairSync(permits);
    }

2.非公平锁

有了前面AQS和ReentrantLock源码分析的基础,再看Semaphore已经简单很多,这里挑重点方法分析下。
(1)acquire方法

	 public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

(2)acquireSharedInterruptibly是AQS中方法

	    public final void acquireSharedInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        if (tryAcquireShared(arg) < 0)
            doAcquireSharedInterruptibly(arg);
    }

(3)tryAcquireShared方法

        protected int tryAcquireShared(int acquires) {
            return nonfairTryAcquireShared(acquires);
        }

(4)nonfairTryAcquireShared

	        final int nonfairTryAcquireShared(int acquires) {
            for (;;) {
            	//得到state值
                int available = getState();
             	//获得剩余许可证的值
                int remaining = available - acquires;
                //剩余许可证为负数,返回后加入同步队列
                //如果许可证大于0,重置state值
                if (remaining < 0 ||
                    compareAndSetState(available, remaining))
                    return remaining;
            }
        }

3.公平锁

公平锁和上一篇分析的类似,都是先判断队列中是否已有线程在等待,有的话加入等待队列,没有的话和非公平锁一样
(1)tryAcquireShared

        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;
            }
        }
    }

4.释放锁

释放锁很简单,就是将许可证增加。
(1)tryReleaseShared

        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;
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值