java acquire()_Semaphore acquire方法过程实现源代码

Semaphore 代码执行的流程,分析acquire的过程

信号量在多线程中有着重要的应用,它的原理是将资源抽象成信号量,如果信号量大于0表明有可用资源,小于0,则需要等待。

对应申请时,就是做信号量减操作;

对应释放时,就是做信号量加操作。

资源又抽象成state,这是个所有线程都可见的变量。通过state就可以判断线程是不是可以访问共享资源了。

1.new Semaphore()对象时,它调用的 sync = new NonfairSync(permits);可以看出它是调用非公平的同步辅助类,其中sync的类型是Sync,它的定义如下:

abstract static class Sync extends AbstractQueuedSynchronizer{};

2.NonfairSync类又继承Sync类,它具体实现如下:

final static class NonfairSync extends Sync {

private static final long serialVersionUID = -2694183684443567898L;

NonfairSync(int permits) {

super(permits);

/*此处调用的是Sync(int permits) {

setState(permits);

}

最终state的定义是这样的private volatile int state;

这个state对所有的线程是可见的,并且是最新的值。

*/

}

//这个是在第三步中的acquireSharedInterruptibly()方法被调用

protected int tryAcquireShared(int acquires) {

return nonfairTryAcquireShared(acquires);

}

}

3.看看acquire()方法的执行过程

先是调用如下的方法:

public void acquire() throws InterruptedException {

sync.acquireSharedInterruptibly(1);

}

acquireSharedInterruptibly(1) 这个方法调用下面这个方法:

public final void acquireSharedInterruptibly(int arg) throws InterruptedException {

if (Thread.interrupted())

throw new InterruptedException();

//如果小于0,表明没有资源了,就要进入队列中去

if (tryAcquireShared(arg) < 0)

doAcquireSharedInterruptibly(arg);

}

4.tryAcquireShared()方法调用nonfairTryAcquireShared()方法,看看它的具体是怎样实现。

final int nonfairTryAcquireShared(int acquires) {

for (;;) {

//最新的state值

int available = getState();

//还剩下多少个许可证了(permit)

int remaining = available - acquires;

//只有在还剩有时才更新状态

if (remaining < 0 ||

compareAndSetState(available, remaining))

return remaining;

}

}

5.如果没有许可证了,就要进入队列中去了,看看doAcquireSharedInterruptibly()这个方法的实现

private void doAcquireSharedInterruptibly(int arg)

throws InterruptedException {

final Node node = addWaiter(Node.SHARED);

/*

private Node addWaiter(Node mode) {

Node node = new Node(Thread.currentThread(), mode);

Node pred = tail;

if (pred != null) {

node.prev = pred;

if (compareAndSetTail(pred, node)) {

pred.next = node;

return node;

}

}

//进入队列

enq(node);

return node;

}

*/

try {

for (;;) {

final Node p = node.predecessor();

if (p == head) {

int r = tryAcquireShared(arg);

if (r >= 0) {

setHeadAndPropagate(node, r);

p.next = null; // help GC

return;

}

}

if (shouldParkAfterFailedAcquire(p, node) &&

parkAndCheckInterrupt())

break;

}

} catch (RuntimeException ex) {

cancelAcquire(node);

throw ex;

}

// Arrive here only if interrupted

cancelAcquire(node);

throw new InterruptedException();

}

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30024515/viewspace-1431830/,如需转载,请注明出处,否则将追究法律责任。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值