package cn.semaphore.n1;
import java.util.concurrent.Semaphore;
public class Pool {
private static final int MAX_AVAILABLE=2;
private final Semaphore available=new Semaphore(MAX_AVAILABLE, true);
private Connection[] items=new Connection[MAX_AVAILABLE];
public Pool(){
for(int i=0;i<MAX_AVAILABLE;i++){
items[i]=new Connection(i+1);
}
}
private boolean[] used=new boolean[MAX_AVAILABLE];
public Connection getItem() throws InterruptedException{
available.acquire();
return getNextAvailableItem();
}
public boolean putItem(Connection x){
if(markAsUnused(x)){
available.release();
return true;
}else{
return false;
}
}
private synchronized Connection getNextAvailableItem(){
for(int i=0;i<MAX_AVAILABLE;i++){
if(!used[i]){
used[i]=true;
return items[i];
}
}
return null;
}
private synchronized boolean markAsUnused(Connection x){
for(int i=0;i<MAX_AVAILABLE;i++){
if(x.getId()==items[i].getId()){
if(used[i]){
used[i]=false;
return true;
}else{
return false;
}
}
}
return false;
}
}
package cn.semaphore.n1;
public class Connection {
private int id;
public Connection(int i){
id=i;
}
public String toString() {
return "Connection [id=" + id + "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
package cn.semaphore.n1;
import java.util.Random;
public class St1 {
public static void main(String[] args) {
final Pool pool = new Pool();
final Random random = new Random();
for(int i=0;i<12;i++){
new Thread(new Runnable() {
public void run() {
int nextInt = random.nextInt(3000);
try {
Thread.sleep(nextInt);
Connection item = pool.getItem();
System.out.println(Thread.currentThread().getName()+" 获取连接"+item);
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName()+" 释放连接"+item+" "+pool.putItem(item));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
这是信号量的一个简单应用,获取连接前先获取许可,释放连接后要释放许可。
输出:
Thread-7 获取连接Connection [id=1]
Thread-5 获取连接Connection [id=2]
Thread-7 释放连接Connection [id=1] true
Thread-9 获取连接Connection [id=1]
Thread-5 释放连接Connection [id=2] true
Thread-4 获取连接Connection [id=2]
Thread-9 释放连接Connection [id=1] true
Thread-6 获取连接Connection [id=1]
Thread-4 释放连接Connection [id=2] true
Thread-1 获取连接Connection [id=2]
Thread-6 释放连接Connection [id=1] true
Thread-11 获取连接Connection [id=1]
Thread-1 释放连接Connection [id=2] true
Thread-0 获取连接Connection [id=2]
Thread-11 释放连接Connection [id=1] true
Thread-2 获取连接Connection [id=1]
Thread-0 释放连接Connection [id=2] true
Thread-3 获取连接Connection [id=2]
Thread-2 释放连接Connection [id=1] true
Thread-8 获取连接Connection [id=1]
Thread-3 释放连接Connection [id=2] true
Thread-10 获取连接Connection [id=2]
Thread-8 释放连接Connection [id=1] true
Thread-10 释放连接Connection [id=2] true
源码:
Semaphore(int permits) 初始化资源数,默认使用非公平锁,第二个参数设置为true公平锁。
acquire 获取资源,使用AQS共享模式获取资源。
非公平锁 tryAcquireShared:aqs共享模式尝试获取资源:自旋 获取aqs资源数,对资源数-1,如果剩余资源数小于0或者cas修改资源数为剩余资源数成功,则返回,否则自旋。
公平锁 tryAcquireShared:自旋 如果线程等待队列有节点等待获取资源,失败返回-1,否则 获取资源数,对资源数-1,如果剩余资源数小于0或者cas修改资源数成功,则返回 否则自旋。
release 释放资源,使用AQS共享模式释放资源。
tryReleaseShared aqs共享模式 尝试释放资源:自旋 获取资源数,cas操作对资源数+1,成功返回true,失败自旋。