文章目录
Semaphore
和 synchronized、ReentrantLock 不同的是,Semaphore 允许多个线程访问同一个资源,常常用作限制对一个资源的访问线程数。
Semaphore使用,模拟公交车
import java.util.concurrent.Semaphore;
/**
* 模拟公交车(火车)
* 信号量: 信号量维护了一些许可证,每一个 acquire() 方法在获取到许可证之前,如果当前没有可用的许可 证,就会被阻塞,然后才能拿到许可证。 每个release() 方法添加一个许可证,潜在得释放一个被阻塞的获取者。但是,并没有实际的许可证,Semaphore 只是维护了可用许可证的数量。
* 信号量常常用来限制访问某些资源(物理的或逻辑的)的线程数量
* @author ljx
* @Date Jan 16, 2019 10:34:51 AM
*/
public class Bus {
private final static int SEAT_MAX = 5;
private Semaphore tickets = new Semaphore(SEAT_MAX);
private boolean[] used = new boolean[SEAT_MAX];
// 上车买票,然后得到一个座位
public int getSeat() throws InterruptedException {
tickets.acquire();
return getAviliableSeat();
}
// 下车
public void debus(int i) {
markAsUnused(i);
tickets.release();
}
private synchronized int getAviliableSeat() {
for (int i = 0; i < SEAT_MAX; i++) {
if (!this.used[i]) {
used[i] = true;
return i + 1;
}
}
return -1;
}
private synchronized void markAsUnused(int i) {
this.used[i - 1] = false;
}
}
执行:
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* 信号量: 信号量维护了一些许可证,每一个 acquire() 方法在获取到许可证之前,如果当前没有可用的许可证,就会被阻塞,然后才能拿到许可证。 每个
* release() 方法添加一个许可证,潜在得释放一个被阻塞的获取者。但是,并没有实际的许可证,Semaphore 只是维护了可用许可证的数量。
*
* 信号量常常用来限制访问某些资源(物理的或逻辑的)的线程数量
*
* @author ljx
* @Date Jan 16, 2019 9:58:47 AM
*
*/
public class SemaphoreTest {
static class Passenger implements Runnable {
private Bus bus;
private String name;
public Passenger(Bus bus, String name) {
this.bus = bus;
this.name = name;
}
@Override
public void run() {
try {
int seat = bus.getSeat();
System.out.println("Passenger " + name + " get a seat: " + seat);
Thread.sleep((int) (Math.random() * 5000));
bus.debus(seat);
System.out.println(" Passenger " + name + " debus,seat: " + seat + " is useable");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}