Java并发编程--JUC并发工具类之Semaphore

摘要

  • 本文介绍Semaphore相关技术

  • 本文基于jdk1.8

Semaphore介绍

  • Semaphore(信号量)是一种用于多线程编程的同步工具,用于控制同时访问某个资源的线程数量。

  • Semaphore维护了一个计数器,线程可以通过调用acquire()方法来获取Semaphore中的许可证,当计数器为0时,调用acquire()的线程将被阻塞,直到有其他线程释放许可证;

  • 线程可以通过调用release()方法来释放Semaphore中的许可证,这会使Semaphore中的计数器增加,从而允许更多的线程访问共享资源。

Semaphore常用方法

方法 描述
Semaphore(int permits) 构造函数,创建具有给定许可数的Semaphore对象
Semaphore(int permits,boolean fair) 构造函数,创建具有给定许可数的Semaphore对象,fair 表示公平性,如果这个设为 true 的话,下次执行的线程会是等待最久的线程
int availablePermits() 返回当前可用的许可数
void acquire() 获取一个许可,如果没有可用的许可,则阻塞直到有可用的许可
void release() 释放一个许可
boolean tryAcquire() 尝试获取一个许可,如果有可用的许可,则获取成功,返回true;否则返回false

Semaphore代码示例

  • 在这个示例中,Semaphore的初始许可数为2,意味着最多允许两个线程同时访问共享资源。

  • 每个工作线程在执行工作前都会请求一个许可,如果许可可用,它将获得许可并执行工作,然后释放许可供其他线程使用。

  • 如果没有可用的许可,线程将被阻塞直到有可用的许可为止。通过Semaphore的控制,最多允许两个线程并发执行,而第三个线程需要等待前面的线程释放许可后才能执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import java.util.concurrent.Semaphore;

public class SemaphoreConcurrencyExample {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(2); // 创建Semaphore对象,限制并发数为2

// 创建并启动三个线程
Thread thread1 = new Thread(new Worker(semaphore, "Thread 1"));
Thread thread2 = new Thread(new Worker(semaphore, "Thread 2"));
Thread thread3 = new Thread(new Worker(semaphore, "Thread 3"));

thread1.start();
thread2.start();
thread3.start();
}
}

class Worker implements Runnable {
private final Semaphore semaphore;
private final String name;

public Worker(Semaphore semaphore, String name) {
this.semaphore = semaphore;
this.name = name;
}

@Override
public void run() {
try {
System.out.println(name + " is waiting for a permit.");
semaphore.acquire(); // 获取许可

System.out.println(name + " has acquired a permit.");
// 模拟工作
Thread.sleep(2000);

System.out.println(name + " is releasing the permit.");
semaphore.release(); // 释放许可
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Semaphore应用场景

  • 限流:Semaphore可以用于限制对共享资源的并发访问数量,以控制系统的流量。

  • 资源池:Semaphore可以用于实现资源池,以维护一组有限的共享资源