网站托管工作室,郑州专业做网站公司,如何用api做网站,企业门户网站制作文章目录 核心思想#xff1a;停车场模型 #x1f17f;️最简单易懂的代码示例代码解析运行效果分析 核心思想#xff1a;停车场模型 #x1f17f;️
想象一个只有 3个车位 的小型停车场。Semaphore 就好比是这个停车场的入口管理员。 Semaphore semaphore new Semaphore… 文章目录 核心思想停车场模型 ️最简单易懂的代码示例代码解析运行效果分析 核心思想停车场模型 ️
想象一个只有 3个车位 的小型停车场。Semaphore 就好比是这个停车场的入口管理员。 Semaphore semaphore new Semaphore(3); 这就等于创建了一个有3个固定车位的停车场。这个 3 就是“许可证”的数量。 semaphore.acquire(); (获取许可) 一辆车开到停车场入口。管理员acquire方法会检查“里面还有空位吗”如果有空位管理员放行车开进去同时他会把可用车位的数量减一。如果没空位管理员会说“满了请在门口排队等着。” 这辆车这个线程就会被阻塞在入口处排队。 semaphore.release(); (释放许可) 停车场里的一辆车办完事要开走。它开出出口时管理员release方法看到了就把可用车位的数量加一。同时管理员会朝门口排队的车辆大喊“空出来一个位子排在第一的那辆车可以进来了”
Semaphore 就是用这个简单的“计数”方式来控制同时能访问某个资源的线程数量。 最简单易懂的代码示例
下面我们就用代码来模拟 8辆车抢3个车位 的场景。
package Semaphore;
import java.util.Random;
import java.util.concurrent.Semaphore;public class SimpleSemaphoreDemo {public static void main(String[] args) {// 1. 创建一个 Semaphore设定许可证数量为 3即3个停车位Semaphore semaphore new Semaphore(3);// 2. 模拟8个线程8辆车for (int i 1; i 8; i) {final int carNumber i;new Thread(() - {try {System.out.println(车辆 carNumber 到达停车场门口等待进入...);// 3. 尝试获取一个许可证尝试进入停车场// 如果没有许可证线程会在这里阻塞等待semaphore.acquire();// --- 成功获取到许可证后才能执行下面的代码 ---System.out.println( 车辆 carNumber 成功进入停车场);// 模拟停车时间System.out.println( 车辆 carNumber 正在停车...);Thread.sleep(new Random().nextInt(3000) 1000); // 随机停1-4秒} catch (InterruptedException e) {e.printStackTrace();} finally {// 4. 释放许可证车辆离开停车场// 这个操作必须放在 finally 块中确保即使发生异常许可证也一定会被释放System.out.println( 车辆 carNumber 驶出停车场。);semaphore.release();}}).start();}}
}
代码解析
new Semaphore(3): 创建了一个容量为3的信号量代表我们的停车场只有3个车位。semaphore.acquire(): 这是线程获取“门票”的关键一步。如果“门票”发完了3个车位都占满了其他线程就会在这里停下来进入阻塞状态老老实实地排队。Thread.sleep(...): 模拟线程获取到资源后正在使用它的过程即车辆停在车位里的时间。semaphore.release(): 这是最重要的一步线程使用完资源后必须“交还门票”这样其他正在排队等待的线程才有机会获取到资源。把它放在 finally 块里是一个好习惯能保证无论业务代码是否抛出异常锁都能被释放。
运行效果分析 当你运行这个程序时你会清晰地看到
控制台会立刻打印出3条 “ 车辆 x 成功进入停车场” 的信息。剩下的5个线程会停在 “等待进入...” 这一步说明它们被阻塞了。过了1-4秒后每当有一个 “ 车辆 x 驶出停车场。” 的信息出现几乎在同一时间就会有一个新的 “ 车辆 y 成功进入停车场” 出现。
这个过程完美地展示了 Semaphore 如何像一个停车场管理员一样精确地控制着同时办事的线程数量。