源码分析-Semaphor
Posted 千念飞羽
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了源码分析-Semaphor相关的知识,希望对你有一定的参考价值。
semaphore
java中的Semaphore主要用来限制线程的数量。而不是用来限制资源的访问。Semaphore所拥有的集是非常抽象的集合。所以说Semaphore在获取和是否的过程中不会持有特定对象的锁。
即使排除java的语义概念,锁和信号量,虽然都是基于等待唤醒机制,但是也是不同的同步组件。虽然锁可以用来做同步器,同步器可以用来做锁,但是信号量并没有所有者的概念。由于没有所有者的概念,信号量一般用来限制线程数量,而锁用来控制资源访问。这样有什么好处,一个例子就是在死锁恢复的过程中,如果你用的是锁,那必须又拥有这个锁的拥有者去释放,如果你用的是信号量就不需要拥有者去释放这个线程。比如你可以设定在线程终止时自动释放。这样就不会绑定特定的拥有者。
主要方法
从结构上说Semaphore的构成比较简单,就是内部有三个类,一个Sync继承自AQS。这个Sync是一个抽象类,下面继承了2个类分别是NonfairSync和FairSync两个具体的子类,在构造的时候选择使用哪一个。
只要搞懂AQS,Semaphore的内容很简单。
Semaphore的方法基本上没有什么可以说的,这里就看一下这三个类的主要方法就可以了:
Sync
abstract static class Sync extends AbstractQueuedSynchronizer
private static final long serialVersionUID = 1192457210091910933L;
Sync(int permits)
setState(permits);
final int getPermits()
return getState();
final int nonfairTryAcquireShared(int acquires) //这里主要是非公平锁的实现方式,但是我有一点不太明白为什么要写在Sync并且用final,如果我来写的话我会放在NonfairTryAcquireShared中间。这个也是通常实现获取非公平共享锁的典型形式。
for (;;)
int available = getState();
int remaining = available - acquires;
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;
NonfairSync
非公平锁的实现比较简单只要委托给tryAcquireShared就行
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);
FairSync
公平锁的实现
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())//和非公平锁的实现的区别就是这里加了这一条这个是AQS的方法用来判断当前是否有线程排队获取锁。其他内容和非公平锁一致。
return -1;
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
以上是关于源码分析-Semaphor的主要内容,如果未能解决你的问题,请参考以下文章