面试题答案
一键面试信号量的应用场景
- 资源访问控制:当系统中存在有限数量的共享资源(如数据库连接池中的连接、线程池中的线程等),需要限制同时访问这些资源的线程数量时,可以使用信号量。例如,在一个多线程的Web应用中,数据库连接是有限的资源,为了避免过多线程同时竞争连接导致数据库性能下降,可通过信号量来控制同时获取连接的线程数。
- 并发控制:在某些情况下,需要控制并发执行的线程数量,以确保系统的稳定性和性能。比如,一个系统对外部接口的调用频率有限制,为防止过多线程同时调用导致接口被封禁,使用信号量来限制同时调用接口的线程数。
使用Java的Semaphore
类实现资源访问控制场景示例
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
// 创建一个信号量,允许同时有2个线程访问资源
private static final Semaphore semaphore = new Semaphore(2);
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(new Worker(i));
thread.start();
}
}
static class Worker implements Runnable {
private int id;
public Worker(int id) {
this.id = id;
}
@Override
public void run() {
try {
// 获取信号量许可
semaphore.acquire();
System.out.println("线程 " + id + " 获得许可,开始访问资源");
// 模拟访问资源的操作
Thread.sleep(2000);
System.out.println("线程 " + id + " 访问资源完毕,释放许可");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放信号量许可
semaphore.release();
}
}
}
}
在上述示例中,Semaphore
被初始化为允许同时有2个线程获取许可访问资源。每个线程在访问资源前调用acquire()
方法获取许可,如果没有可用许可则等待。访问完资源后通过release()
方法释放许可,以便其他线程可以获取许可访问资源。