Semaphoreの紹介と使用
12090 ワード
さぎょう
主に共有ロックメカニズムを運用する.特定のリソースに同時にアクセスするスレッドの数を制御し、トラフィック制御に使用し、state値で判断し、state>0の場合、新しいスレッドの実行を許可する.state=0の場合、新しいスレッドの実行は許可されません.ループ実行は、マルチスレッド環境で条件が満たされていない場合に再取得されます.
1)取得ロックacquire()のint remaining=available(現在のstate)-acquires(メソッドsync.acquireSharedInterruptibly(1)のパラメータ値1)に従って
final int nonfairTryAcquireShared(int acquires) {
for (;;) {
int available = getState();
int remaining = available - acquires;
if (remaining < 0 || // state=0,
compareAndSetState(available, remaining)) // state>0,
return remaining;
}
}
state数が0未満の場合、待機キューへの参加がブロックされます.そうしないと、実行に成功します.
2)リリースロックacquire()のint next=current(現在のstate)+releases(メソッドsync.releaseShared(1)のパラメータ値1)に従って
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;
}
}
compareAndSetState(current,next)が成功すると、戻りが終了します.
ケース
public class DBPoolSemaphore {
private final static int POOL_SIZE = 10;
private final Semaphore useful,useless;//useful ,useless
public DBPoolSemaphore() {
this. useful = new Semaphore(POOL_SIZE);
this.useless = new Semaphore(0);
}
//
private static LinkedList<Connection> pool = new LinkedList<Connection>();
//
static {
for (int i = 0; i < POOL_SIZE; i++) {
pool.addLast(SqlConnectImpl.fetchConnection());
}
}
/* */
public void returnConnect(Connection connection) throws InterruptedException {
if(connection!=null) {
System.out.println(" "+useful.getQueueLength()+" !!"
+" :"+useful.availablePermits());
useless.acquire();
synchronized (pool) {
pool.addLast(connection);
}
useful.release();
}
}
/* */
public Connection takeConnect() throws InterruptedException {
useful.acquire();
Connection conn;
synchronized (pool) {
conn = pool.removeFirst();
}
useless.release();
return conn;
}
}
Semaphoreを使用する場合、state値を初期化し、ロックを取得すると-1、ロックを解放すると+1となり、state<0の値からロックを取得し続けることができるか否かを判断する