Semaphoreの紹介と使用


さぎょう


主に共有ロックメカニズムを運用する.特定のリソースに同時にアクセスするスレッドの数を制御し、トラフィック制御に使用し、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の値からロックを取得し続けることができるか否かを判断する